本文主要简单讲述了spring cloud组件简单集成的配置及代码(只有简单使用方法,没有原理之类的讲解)。
代码github地址:https://github.com/wkcaeser/spring-cloud-demo/tree/master
Netflix-eureka
eureka server
eureka server主要提供服务注册和发现的功能
依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
配置文件:
spring.application.name=eureka-server
server.port=9081
# 注册中心地址
eureka.instance.hostname=www.wk-1.com
# 关闭eureka server 自己向自己注册功能
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
# 服务注册地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
启动类上加上@EnableEurekaServer注解:
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
eureka-client
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置:
spring.application.name=eureka-client
server.port=9091
# 对外访问地址
eureka.instance.hostname=www.wk02.com
# 服务注册地址
eureka.client.service-url.defaultZone=http://www.wk01.com:9081/eureka/
netflix-ribbon
ribbon用来做负载均衡,负载均衡一般有两种方式,一种是类似于nginx,在服务端做请求转发;还一种是在客户端维护服务列表,然后根据一定策略访问服务。ribbon采用的第二种。
ribbon使用方式有两种:
1、结合restTemplate使用
2、结合Feign使用
结合restTemplate使用
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
配置:
spring.application.name=eureka-ribbon-client
server.port=9071
eureka.instance.hostname=www.wk04.com
eureka.client.service-url.defaultZone=http://www.wk01.com:9081/eureka/
代码:
// restTemplate与ribbon结合的配置
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
// 启动类
@SpringBootApplication
@EnableEurekaClient
public class EurekaRibbonClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonClientApplication.class, args);
}
}
// 暴露给外部访问,内部通过restTemplate结合Ribbon访问eureka provider service的服务 (正常应该是service层)
@RestController
public class HelloController {
private final RestTemplate restTemplate;
@Autowired
public HelloController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/hello")
public String hello(){
// 请求地址写服务名称即可
return restTemplate.getForObject("http://eureka-client/hello", String.class);
}
}
在eureka-client应用中提供如下访问接口,并开启不同端口的多个实例:
@RestController
public class HelloController {
@Value("${server.port}")
private int port;
@GetMapping("/hello")
public String hello(){
return "hello, this app port is " + port;
}
}
游览器访问http://127.0.0.1:9701/hello, 即可发现各个端口被轮流访问。
Feign
Feign默认集成了Ribbon
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
配置:
server.port=9061
spring.application.name=eureka-feign-client
eureka.client.service-url..defaultZone=http://www.wk01.com:9081/eureka/
代码:
//Feign配置类
@Configuration
public class FeignConfig {
@Bean
public Retryer feignRetryer() {
// 失败后尝试
return new Retryer.Default(100, SECONDS.toMillis(1), 5);
}
}
// Feign client配置
// value为要访问的服务名称,configuration为Feign的配置类
@FeignClient(value = "eureka-client", configuration = FeignConfig.class)
public interface EurekaClientFeign {
@GetMapping("/hello")
String hello();
}
// 外部服务调用 正常应该有service层
@RestController
public class HelloController {
final
EurekaClientFeign eurekaClientFeign;
@Autowired
public HelloController(EurekaClientFeign eurekaClientFeign) {
this.eurekaClientFeign = eurekaClientFeign;
}
@GetMapping("/hello")
public String hello(){
return eurekaClientFeign.hello();
}
}
Hystrix
hystrix是Netflix开源的组件,提供熔断器功能。
restTemplate和Ribbon做负载均衡时使用Hystrix
在restTemplate和Ribbon配合使用的依赖上增加Hystrix的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
在main方法上加入@EnableHystrix开启熔断器功能。
在调用restTemplate的地方加上@HystrixCommand注解,fallbackMethod参数表示当服务不可用时,回退方案调用的方法。
@RestController
public class HelloController {
private final RestTemplate restTemplate;
@Autowired
public HelloController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/hello")
@HystrixCommand(fallbackMethod = "error")
public String hello(){
return restTemplate.getForObject("http://eureka-client/hello", String.class);
}
public String error() {
return "service error";
}
}
调用接口,观察返回结果;关闭eureka的provider服务,再次调用观察结果;再打开provider服务,再次调用观察结果。即可观察到Hystrix生效了。
feign使用Hystrix
feign的起步依赖中不仅包含有ribbon的依赖,Hystrix依赖同样包含,故不需要引入新的依赖,只需开启Hystrix配置即可。
feign.hystrix.enabled=true
然后在Feign client接口的注解参数上配置fallback操作的实现类即可。
@FeignClient(value = "eureka-client", configuration = FeignConfig.class, fallback = FallbackHystrix.class)
public interface EurekaClientFeign {
@GetMapping("/hello")
String hello();
}
@Component
public class FallbackHystrix implements EurekaClientFeign {
@Override
public String hello() {
return "service error, Feign";
}
}
使用Hystrix Dashboard监控熔断器状态
restTemplate配合Ribbon或者 Feign的配置没区别
首先,引入Actuator、Hystrix Dashboard和Hystrix的起步依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-hystrix-dashboard -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
在启动类上加入@EnableHystrix和@EnableHystrixDashboard两个注解
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
@EnableHystrixDashboard
public class EurekaFeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaFeignClientApplication.class, args);
}
}
访问http://www.wk04.com:9061/hystrix即可访问Hystrix Dashboard的ui界面
zuul
zuul是spring cloud的网关组件,包含动态路由、过滤、监控、安全等功能。
zuul是通过servlet实现的,自定义的zuulServlet类似于DispatchServlet对请求进行控制,zuul的核心是一系列过滤器,在整个请求期间进行操作。
包含四种过滤器:
- PRE过滤器:请求路由到具体服务之前执行,可以做身份验证、参数验证等
- ROUTING 过滤器:用于将请求路由到具体的微服务实例。默认使用httpClient进行网络请求。
- POST过滤器:请求在被路由到具体微服务实例后执行。用于统计等功能,以及将响应结果返回客户端。
- ERROR过滤器:在其他过滤器发生错误后执行。
使用
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
配置:
spring.application.name=eureka-zuul-client
server.port=9051
eureka.client.service-url.defaultZone=http://www.wk01.com:9081/eureka/
# helloapi为自定义的参数 这个配置的含义为所有hello开头的url都会被分配到服务名为eureka-client的服务上
# 这个可以配置多个,定义不同的自定义参数即可
# service-id不是必须的,在使用了ribbon做负载均衡的时候才需要 没负载均衡的时候可以直接指定url,不过不推荐(方法见下面配置)
zuul.routes.helloapi.path=/hello/**
zuul.routes.helloapi.service-id=eureka-client
# 可以用来配置版本号
zuul.prefix=/v1
## 使用url做负载均衡的配置方法 自己维护注册列表
## 关闭ribbon的向eureka client获取服务器注册列表的功能
#ribbon.eureka.enabled=false
#hellapi-l.ribbon.listOfServers=http://127.0.0.1:9091,http://127.0.0.1:9092
代码:
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class EurekaZuulClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaZuulClientApplication.class, args);
}
}
具体过滤器的使用这里不具体讲了。
config
config server
依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
配置:
application.properties
server.port=9041
spring.application.name=config-server
# 配置从本地shared目录下读取配置 还能配置从git等读取配置
spring.profiles.active=native
spring.cloud.config.server.native.search-locations=classpath:/shared
config-client-dev.properties(文件命名规则类似于springboot的配置文件加载方式,不过前缀是config-client)
name=wk
age=23
version=1
代码:
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
config client
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
配置文件(注意这里在bootstrap.properties(yml)配置,而不要在application中配置,bootstrap配置文件先加载):
spring.application.name=config-client
server.port=9042
spring.cloud.config.uri=http://127.0.0.1:9041
spring.cloud.config.fail-fast=true
spring.profiles.active=dev
代码:
@SpringBootApplication
@RestController
public class ConfigClientApplication {
@Value("${name}")
private String name;
@GetMapping("/")
public String test() {
return name;
}
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class, args);
}
}