SpringCloud基础
SpringCloud极大的简化了分布式系统的开发,实现了微服务的快速部署和灵活应用
SpringCloud主要框架
* 服务发现--Netfix Eureka
* 服务调用--Netfix Feign
* 熔断器--Netfix Hystrix
* 服务网关--Netfix Zuul
* 分布式配置--Spring Cloud Config
* 消息总线--Spring Cloud Bus
注意SpringCloud和SpringBoot版本要一一对应,不然会报错
一。Eureka服务发现
外部的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>tensquare_eureka</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<groupId>com.jinke</groupId>
<artifactId>springboot</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
内部的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot</artifactId>
<groupId>com.jinke</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>tensquare_eureka</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 6868
eureka:
client:
register-with-eureka: false
fetch-registery: false
service-url:
defaultZone: http://127.0.0.1:${server.port}/eureka/
EurekaServer.java
package com.tensquare.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class);
}
}
直接启动看
二。Eureka服务注册
新建一个module
在pom.xml中增加
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
application.yml
server:
port: 9004
spring:
application:
name: register
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka/
instance:
prefer-ip-address: true
RegisterApplication.java
package com.example.register;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class RegisterApplication {
public static void main(String[] args) {
SpringApplication.run(RegisterApplication.class, args);
}
}
applicaiton跑起来,看结果已经注册成功了
三。服务调用
被调register的LabelController
package com.example.register.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/label")
@CrossOrigin
public class LabelController {
@RequestMapping(value = "/{labelId}", method = RequestMethod.GET)
public String findById(@PathVariable("labelId") String id) {
System.out.println("调用成功");
return "success";
}
}
主调register2的ProblerController
package com.example.register2.controller;
import com.example.register2.client.BaseClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@CrossOrigin
@RequestMapping("/problem")
public class ProblemController {
@Autowired
private BaseClient baseClient;
@RequestMapping(value = "/label/{labelId}", method = RequestMethod.GET)
public String findByLabelId(@PathVariable String labelId) {
baseClient.findById(labelId);
return "success";
}
}
application
package com.example.register2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class Register2Application {
public static void main(String[] args) {
SpringApplication.run(Register2Application.class, args);
}
}
BaseClient
package com.example.register2.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient("register")
public interface BaseClient {
@RequestMapping(value = "/label/{labelId}", method = RequestMethod.GET)
public String findById(@PathVariable("labelId") String labelId);
}
eureka和register、register2服务都分别跑起来
同时可以看到register的控制台输出了“调用成功”,即代表调用其他服务成功
Spring已经实现了负载均衡,即调用服务集群时,会公平的轮流调用其中的服务
四。熔断器
熔断器可以有效避免雪崩现象
当被调服务挂掉以后,会走熔断器里面的内容
调用的服务增加实现类
package com.example.register2.client.impl;
import com.example.register2.client.BaseClient;
import org.springframework.stereotype.Component;
@Component
public class BaseClientImpl implements BaseClient {
@Override
public String findById(String labelId) {
System.out.println("熔断器触发了");
return "success";
}
}
application.yml增加
feign:
hystrix:
enabled: true
五。网关
网关的作用就相当于一个中转分发站,接口
新建一个网关
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot</artifactId>
<groupId>com.jinke</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>manager</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 9011
spring:
application:
name: manager
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka/
instance:
prefer-ip-address: true
zuul:
routes:
register:
path: /register/**
serviceId: register
application
package com.jinke.manager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ManagerApplication {
public static void main(String[] args) {
SpringApplication.run(ManagerApplication.class);
}
}
然后启动服务即可
六。网关过滤
在网关模块新建一个过滤类即可
package com.jinke.manager.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
@Component
public class ManagerFilter extends ZuulFilter {
@Override
public String filterType() {
//过滤器类型:之前或之后
return "pre";
}
@Override
public int filterOrder() {
//多个过滤器的执行顺序
return 0;
}
@Override
public boolean shouldFilter() {
//是否开启该过滤器
return true;
}
@Override
public Object run() throws ZuulException {
//如果设置setsendzullResponse(false)表示不再继续执行
System.out.println("已经执行到最后了");
return null;
}
}
七。SpringCloudConfig配置
新建config的module
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot</artifactId>
<groupId>com.jinke</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>config</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
</dependencies>
</project>
application.xml
server:
port: 12000
spring:
application:
name: config
cloud:
config:
server:
git:
uri: https://gitee.com/king1039/springcloud-config.git
username: xxxxxxx@qq.com
password: xxxxxx
application
package com.jinke.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class);
}
}
服务跑起来,如果提示Authentication is required but no CredentialsProvider has been registered是因为要账号密码验证,在配置文件填上
在git上修改以后,刷新会得到新的结果
下面通过配置来调用服务
新建一个base的module
bootstrap.myl
spring:
cloud:
config:
name: springcloud
profile: config
label: master
uri: http://127.0.0.1:12000
git上的配置文件springcloud-config.yml
server:
port: 9001
spring:
application:
name: base
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka/
instance:
prefer-ip-address: true
开启eureka、config、base三个服务,然后调用
流程就是先读取Git上的配置,然后拉下来,再调用服务
下面来通过bus消息开启监听
config的配置文件application.yml
server:
port: 12000
spring:
application:
name: config
cloud:
config:
server:
git:
uri: https://gitee.com/king1039/springcloud-config.git
username: xxxxxxxx@qq.com
password: xxxxxx
rabbitmq:
host: 172.16.10.221
management:
endpoints:
web:
exposure:
include: bus-refresh
被调的服务配置文件
server:
port: 9001
spring:
application:
name: base
rabbitmq:
host: 172.16.10.221
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka/
instance:
prefer-ip-address: true
修改了被调配置文件后,使用post请求发送一次bus-refresh即可实现消息传递
如果要监听自定义的标签需要增加注解@RefreshScope
代码地址:https://github.com/king1039/SpringCloud.git
欢迎关注我的微信公众号:安卓圈