Netflix SpringCloud-ribbon & zipkin

发布于:2023-01-20 ⋅ 阅读:(13) ⋅ 点赞:(0) ⋅ 评论:(0)

本篇继续简述Netflix版SpringCloud之ribbon+hystrix & zipkin。

一些基本组件概念理解:

ribbon: 可以实现负载均衡,feign默认集成了ribbon。

hystrix: 断路器,feign自带断路器,但需要配置开启。

hystrix dashboard: 断路器仪表盘。

zipkin: spring clound sleuth集成了服务链路追踪组件zipkin.

            sleuth进行数据埋点采集,zipkin进行数据存储展示

下面简单演示下以上组件的用法。

准备工作:启动eureka服务注册中心(参见 Netflix SpringCloud-Eureka

1. ribbon负载均衡+hystrix断路机制

1.1 pom

<?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>  <groupId>com.demo</groupId>  <artifactId>routing-ribbon</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>routing-ribbon</name>  <parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>1.5.12.RELEASE</version>    <relativePath/>  </parent>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>1.8</java.version>    <spring-cloud.version>Edgware.SR3</spring-cloud.version>  </properties>  <dependencies>    <!--注册ribbon服务到注册中心-->    <dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>    </dependency>    <!--ribbon-->    <dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>    </dependency>    <!--hystrix断路器-->    <dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-starter-hystrix</artifactId>    </dependency>    <!--Hystrix Dashboard (断路器仪表盘)-->    <!--访问http://localhost:9000/hystrix        在请求地址栏输入:http://localhost:9000/hystrix.stream,        点击Monitor Stream可以监控service层的方法-->    <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-actuator</artifactId>    </dependency>    <dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>    </dependency>    <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-test</artifactId>      <scope>test</scope>    </dependency>  </dependencies>  <dependencyManagement>    <dependencies>      <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-dependencies</artifactId>        <version>${spring-cloud.version}</version>        <type>pom</type>        <scope>import</scope>      </dependency>    </dependencies>  </dependencyManagement>  <build>    <plugins>      <plugin>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-maven-plugin</artifactId>      </plugin>    </plugins>  </build>  <repositories>    <repository>      <id>spring-milestones</id>      <name>Spring Milestones</name>      <url>https://repo.spring.io/milestone</url>      <snapshots>        <enabled>false</enabled>      </snapshots>    </repository>  </repositories></project>

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:

@RestControllerpublic 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:

@RestControllerpublic 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;@Servicepublic 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的错误请求百分比

2. zipkin链路追踪

2.1 zipkin相关依赖

<dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency>  <groupId>io.zipkin.java</groupId>  <artifactId>zipkin-server</artifactId></dependency><dependency>  <groupId>io.zipkin.java</groupId>  <artifactId>zipkin-autoconfigure-ui</artifactId></dependency>

2.2 zipkin yml

spring:  application:    name: server-zipkinserver:  port: 9100  eureka:  client:    serviceUrl:      defaultZone: http://peer1:8888/eureka/,http://peer2:8889/eureka/

2.3 zipkin application

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@EnableEurekaClientpublic class ServerZipkinApplication {  public static void main(String[] args) {    SpringApplication.run(ServerZipkinApplication.class, args);  }}

eureka-client 工程加入zipkin服务追踪

eureka-client pom.xml

<dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-zipkin</artifactId></dependency>

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相关的组件功能。