本篇继续简述Netflix版SpringCloud之ribbon+hystrix & zipkin。
一些基本组件概念理解:
ribbon: 可以实现负载均衡,feign默认集成了ribbon。
hystrix: 断路器,feign自带断路器,但需要配置开启。
hystrix dashboard: 断路器仪表盘。
zipkin: spring clound sleuth集成了服务链路追踪组件zipkin.
sleuth进行数据埋点采集,zipkin进行数据存储展示
下面简单演示下以上组件的用法。
准备工作:启动eureka服务注册中心(参见 Netflix SpringCloud-Eureka)
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.demo
routing-ribbon
0.0.1-SNAPSHOT
jar
routing-ribbon
org.springframework.boot
spring-boot-starter-parent
1.5.12.RELEASE
UTF-8
UTF-8
1.8
Edgware.SR3
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
org.springframework.cloud
spring-cloud-starter-hystrix
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-starter-hystrix-dashboard
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
1.2 yml
spring:
application:
name: routing-ribbon
eureka:
client:
serviceUrl:
defaultZone: http://peer1:8888/eureka/,http://peer2:8889/eureka/
server:
port: 9000
1.3 application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* ribbon是一个负载均衡客户端,可以很好的控制http和tcp的一些行为。
* Feign默认集成了ribbon
*/
@SpringBootApplication
@EnableDiscoveryClient // 向服务注册中心eureka注册ribbon服务组件
@EnableHystrix // 开启断路器
@EnableHystrixDashboard // 开启断路器仪表盘
public class RoutingRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RoutingRibbonApplication.class, args);
}
@Bean // 向spring IOC容器注入一个bean: restTemplate
@LoadBalanced // RestTemplate开启负载均衡功能
RestTemplate restTemplate() {
return new RestTemplate();
}
}
1.4 演示ribbon负载均衡
(1)服务注册中心eureka-server集群,端口为8888,8889(相当于zookeeper)
eureka-client 工程同Netflix SpringCloud-Eureka 第3部分eureka client ,eureka-client工程启动两个实例,端口分别为8887,8886,分别向服务注册中心注册。
(2)eureka-client中定义一个简单的HelloController:
@RestController
public class HelloController {
@Value("${server.port}")
private String port;
/**
* http://localhost:8887/hello?name=bruce
* @param name
* @return
*/
@RequestMapping("/hello")
public String hello(@RequestParam String name) {
return "hello " + name + ",I am from port:" + port;
}
}
(3)routing-ribbon端口为9000(功能类似Nginx),向服务注册中心注册。
routing-ribbon中定义一个简单的HelloController:
@RestController
public class HelloController {
@Autowired
HelloService helloService;
/**
* http://localhost:9000/hello?name=bruce
* @param name
* @return
*/
@RequestMapping(value = "/hello")
public String hello(@RequestParam String name){
return helloService.helloService(name);
}
/**
* http://localhost:9000/hi?name=bruce
* @param name
* @return
*/
@RequestMapping(value = "/hi")
public String hi(@RequestParam String name){
return helloService.hiService(name);
}
}
routing-ribbon中定义的HelloService:
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
/**
* url 中的 eureka-client 即为eureka-client工程中配置的spring-application-name
* 在浏览器上多次访问http://eureka-client/hello?name=bruce,浏览器交替显示:
* hello bruce,I am from port:8887
* hello bruce,I am from port:8886
*
* 这说明当我们通过调用restTemplate.getForObject("http://eureka-client/hello?name=" + name, String.class)方法时,
* 已经做了负载均衡,访问了不同的端口的服务实例。
*
* @param name
* @return
*/
public String helloService(String name) {
return restTemplate.getForObject("http://eureka-client/hello?name=" + name, String.class);
}
/**
* 启动:routing-ribbon 工程,当我们访问http://localhost:9000/hi?name=bruce,浏览器显示:
* hi bruce,i am from port:8887 / hi bruce,i am from port:8886, 当任意关闭一个客户端,仍可以访问;
* 此时全部关闭 eureka-client 工程,当我们再访问http://localhost:9000/hi?name=bruce,浏览器会显示:
* hi,bruce! sorry,error!
* @param name
* @return
*/
@HystrixCommand(fallbackMethod = "hiError") // 指定下面定义的断路处理方法名
public String hiService(String name) {
return restTemplate.getForObject("http://eureka-client/hello?name=" + name, String.class);
}
/**
* 这就说明当 eureka-client 工程不可用的时候,
* routing-ribbon调用 eureka-client的API接口时,会执行快速失败,直接返回一组字符串,
* 而不是等待响应超时,这很好的控制了容器的线程阻塞
* @param name
* @return
*/
public String hiError(String name) {
return "hi," + name + "! sorry,error!";
}
}
(4)当routing-ribbon通过restTemplate调用eureka-client的hello接口时, 因为用ribbon进行了负载均衡,会轮流的调用8887和8886 两个端口的hello接口。
当eureka-client两个节点服务都可用时,反复刷新请求,可见通过ribbon实现了负载均衡;当其中一个client服务节点挂掉后,会一直调用仅存的一个节点服务。
1.5 演示hystrix断路处理
(1)当eureka-client两个节点服务都不可用时,即无可用服务时,这时会触发我们定义好的断路机制,调取 fallbackMethod = "hiError"
(2)如果没有指定断路防护机制,将直接返回springboot定义的默认错误页面
(3)访问hystrix dashboard
在图表中,左上角的圆圈代表了该方法的流量和状态:
圆圈越大代表方法流量越大
圆圈为绿色代表断路器健康、黄色代表断路器偶发故障、红色代表断路器故障
右上角的计数器(三列数字):
第一列从上到下
绿色代表当前成功调用的数量
蓝色代表短路请求的数量
蓝绿色代表错误请求的数量
第二列从上到下
黄色代表超时请求的数量
紫色代表线程池拒绝的数量
红色代表失败请求的数量
第三列
过去10s的错误请求百分比
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
io.zipkin.java
zipkin-server
io.zipkin.java
zipkin-autoconfigure-ui
spring:
application:
name: server-zipkin
server:
port: 9100
eureka:
client:
serviceUrl:
defaultZone: http://peer1:8888/eureka/,http://peer2:8889/eureka/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import zipkin.server.EnableZipkinServer;
/**
* Spring Cloud Sleuth集成了服务追踪组件zipkin
* 依次启动server-zipkin,eureka-client1,eureka-client2,
* 访问server-zipkin http://localhost:9100
*/
@SpringBootApplication
@EnableZipkinServer
@EnableEurekaClient
public class ServerZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(ServerZipkinApplication.class, args);
}
}
eureka-client 工程加入zipkin服务追踪
eureka-client pom.xml
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.cloud
spring-cloud-starter-zipkin
eureka-client yml
eureka:
client:
serviceUrl:
defaultZone: http://peer1:8888/eureka/,http://peer2:8889/eureka/
server:
port: 8887
spring:
application:
name: eureka-client
zipkin:
base-url: http://localhost:9100
访问zipkin监控面板 http://localhost:9100 ,查看服务调用路径
点击查看具体的服务调用:
以上简单演示了下ribbon的负载均衡功能,hystrix的断路处理机制,以及使用zipkin监控追踪服务调用链路。
下章节将简述下feign及zuul相关的组件功能。