使用Ribbon实现客户端侧负载均衡(生灵之焱)

Ribbon简介

简介

        Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。

        在这一章中,我们将具体介绍如何使用Ribbon来实现客户端的负载均衡,并且通过源码分析来了解Ribbon实现客户端负载均衡的基本原理。

客户端负载均衡

        负载均衡在系统架构中是一个非常重要,并且是不得不去实施的内容。因为负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一。我们通常所说的负载均衡都指的是服务端负载均衡,其中分为硬件负载均衡和软件负载均衡。硬件负载均衡主要通过在服务器节点之间按照专门用于负载均衡的设备,比如F5等;而软件负载均衡则是通过在服务器上安装一些用于负载均衡功能或模块等软件来完成请求分发工作,比如Nginx等。不论采用硬件负载均衡还是软件负载均衡,只要是服务端都能以类似下图的架构方式构建起来:

负载均衡架构图

        硬件负载均衡的设备或是软件负载均衡的软件模块都会维护一个下挂可用的服务端清单,通过心跳检测来剔除故障的服务端节点以保证清单中都是可以正常访问的服务端节点。当客户端发送请求到负载均衡设备的时候,该设备按某种算法(比如线性轮询、按权重负载、按流量负载等)从维护的可用服务端清单中取出一台服务端端地址,然后进行转发。

        而客户端负载均衡和服务端负载均衡最大的不同点在于上面所提到服务清单所存储的位置。在客户端负载均衡中,所有客户端节点都维护着自己要访问的服务端清单,而这些服务端端清单来自于服务注册中心,比如上一章我们介绍的Eureka服务端。同服务端负载均衡的架构类似,在客户端负载均衡中也需要心跳去维护服务端清单的健康性,默认会创建针对各个服务治理框架的Ribbon自动化整合配置,比如Eureka中的org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,Consul中的org.springframework.cloud.consul.discovery.RibbonConsulAutoConfiguration。在实际使用的时候,我们可以通过查看这两个类的实现,以找到它们的配置详情来帮助我们更好地使用它。

        通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:

        ▪️服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心。

        ▪️服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。

        这样,我们就可以将服务提供者的高可用以及服务消费者的负载均衡调用一起实现了。

服务消费者整合Ribbon

依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.itmuch.cloud</groupId>
    <artifactId>microservice-consumer-movie-ribbon</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>microservice-consumer-movie-ribbon</name>
    <description>Demo project for Spring Boot</description>


    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <!--引入spring cloud依赖-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR4</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>

</project>

yml

server:
  port: 8010
spring:
  application:
    name: microservice-consumer-movie
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
  instance:
    prefer-ip-address: true

为RestTemplate添加@LoadBalance注解

package com.itmuch.cloud.microserviceconsumermovieribbon;

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.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class MicroserviceConsumerMovieRibbonApplication {

    /**
     * 实例化一个Bean并使用该方法的名字命名
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(MicroserviceConsumerMovieRibbonApplication.class, args);
    }

}

修改controller

package com.itmuch.cloud.microserviceconsumermovieribbon.controller;

import com.itmuch.cloud.microserviceconsumermovieribbon.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class MovieController {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    private static final Logger logger = LoggerFactory.getLogger(MovieController.class);

    /**
     * microservice-provider-user:虚拟主机名
     * @param id
     * @return
     */
    @GetMapping("/user/{id}")
    public User findById(@PathVariable Long id){
        return this.restTemplate.getForObject("http://microservice-provider-user/" + id,User.class);
    }

    @GetMapping("/log-instance")
    public void logUserInstance(){
        ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
        //打印当前选择的那个节点
        MovieController.logger.info("{}:{}:{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
    }
}

 

启动多个服务提供user

依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.itmuch.cloud</groupId>
    <artifactId>microservice-provider-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>microservice-provider-user</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--提供Spring Data Jpa的支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--提供Spring MVC的支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <!--引入spring cloud依赖-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR4</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>


</project>

yml

server:
  port: 8000  8001  #提供两个服务提供者
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/spring_cloud?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 123
    type: com.alibaba.druid.pool.DruidDataSource
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    database: mysql
  application:
    name: microservice-provider-user   #注册到eureka server中的服务名


logging:
  level:
    root: info
    org.hibernate: info
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.hibernate.type.descriptor.sql.BasicExtractor: TRACE

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
  instance:
    prefer-ip-address: true

# #表示讲自己的IP祖册到Eureka Server  如果不配置或者false,则表示注册微服务所在操作系统的hostname到Eureka server

启动类

package com.itmuch.cloud.microserviceprovideruser;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient  //声明这是一个eureka客户端
public class MicroserviceProviderUserApplication {

    public static void main(String[] args) {
        SpringApplication.run(MicroserviceProviderUserApplication.class, args);
    }

}

controller

package com.itmuch.cloud.microserviceprovideruser.controller;


import com.itmuch.cloud.microserviceprovideruser.dao.UserRepository;
import com.itmuch.cloud.microserviceprovideruser.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @GetMapping("/{id}")
    public User findById(@PathVariable Long id){
        User findOne = this.userRepository.findOne(id);
        return findOne;
    }
}

dao

package com.itmuch.cloud.microserviceprovideruser.dao;

import com.itmuch.cloud.microserviceprovideruser.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User,Long> {
}

实体类

package com.itmuch.cloud.microserviceprovideruser.entity;

import javax.persistence.*;
import java.math.BigDecimal;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String username;

    @Column
    private String name;

    @Column
    private Integer age;

    @Column
    private BigDecimal balance;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public BigDecimal getBalance() {
        return balance;
    }

    public void setBalance(BigDecimal balance) {
        this.balance = balance;
    }
}

启动两个,然后启动eureka server集群

测试结果 http://localhost:8010/log-instance

"C:\Program Files\Java\jdk1.8.0_112\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:56625,suspend=y,server=n -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=56624 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:C:\Users\user\.IntelliJIdea2018.2\system\captureAgent\debugger-agent.jar=file:/C:/Users/user/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_112\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\rt.jar;F:\gitsource\guns\stylefeng-guns-master\spring_cloud\microservice-consumer-movie-ribbon\target\classes;D:\m2_repository\org\springframework\boot\spring-boot-starter-web\1.4.3.RELEASE\spring-boot-starter-web-1.4.3.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter\1.4.3.RELEASE\spring-boot-starter-1.4.3.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot\1.4.3.RELEASE\spring-boot-1.4.3.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-autoconfigure\1.4.3.RELEASE\spring-boot-autoconfigure-1.4.3.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-logging\1.4.3.RELEASE\spring-boot-starter-logging-1.4.3.RELEASE.jar;D:\m2_repository\ch\qos\logback\logback-classic\1.1.8\logback-classic-1.1.8.jar;D:\m2_repository\ch\qos\logback\logback-core\1.1.8\logback-core-1.1.8.jar;D:\m2_repository\org\slf4j\jcl-over-slf4j\1.7.22\jcl-over-slf4j-1.7.22.jar;D:\m2_repository\org\slf4j\jul-to-slf4j\1.7.22\jul-to-slf4j-1.7.22.jar;D:\m2_repository\org\slf4j\log4j-over-slf4j\1.7.22\log4j-over-slf4j-1.7.22.jar;D:\m2_repository\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-tomcat\1.4.3.RELEASE\spring-boot-starter-tomcat-1.4.3.RELEASE.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.6\tomcat-embed-core-8.5.6.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.6\tomcat-embed-el-8.5.6.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.6\tomcat-embed-websocket-8.5.6.jar;D:\m2_repository\org\hibernate\hibernate-validator\5.2.4.Final\hibernate-validator-5.2.4.Final.jar;D:\m2_repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;D:\m2_repository\org\jboss\logging\jboss-logging\3.3.0.Final\jboss-logging-3.3.0.Final.jar;D:\m2_repository\com\fasterxml\classmate\1.3.3\classmate-1.3.3.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-databind\2.8.5\jackson-databind-2.8.5.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-annotations\2.8.5\jackson-annotations-2.8.5.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-core\2.8.5\jackson-core-2.8.5.jar;D:\m2_repository\org\springframework\spring-web\4.3.5.RELEASE\spring-web-4.3.5.RELEASE.jar;D:\m2_repository\org\springframework\spring-aop\4.3.5.RELEASE\spring-aop-4.3.5.RELEASE.jar;D:\m2_repository\org\springframework\spring-beans\4.3.5.RELEASE\spring-beans-4.3.5.RELEASE.jar;D:\m2_repository\org\springframework\spring-context\4.3.5.RELEASE\spring-context-4.3.5.RELEASE.jar;D:\m2_repository\org\springframework\spring-webmvc\4.3.5.RELEASE\spring-webmvc-4.3.5.RELEASE.jar;D:\m2_repository\org\springframework\spring-expression\4.3.5.RELEASE\spring-expression-4.3.5.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-actuator\1.4.3.RELEASE\spring-boot-starter-actuator-1.4.3.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-actuator\1.4.3.RELEASE\spring-boot-actuator-1.4.3.RELEASE.jar;D:\m2_repository\org\springframework\cloud\spring-cloud-starter-eureka\1.2.4.RELEASE\spring-cloud-starter-eureka-1.2.4.RELEASE.jar;D:\m2_repository\org\springframework\cloud\spring-cloud-starter\1.1.7.RELEASE\spring-cloud-starter-1.1.7.RELEASE.jar;D:\m2_repository\org\springframework\cloud\spring-cloud-context\1.1.7.RELEASE\spring-cloud-context-1.1.7.RELEASE.jar;D:\m2_repository\org\springframework\security\spring-security-crypto\4.1.4.RELEASE\spring-security-crypto-4.1.4.RELEASE.jar;D:\m2_repository\org\springframework\cloud\spring-cloud-commons\1.1.7.RELEASE\spring-cloud-commons-1.1.7.RELEASE.jar;D:\m2_repository\org\springframework\security\spring-security-rsa\1.0.3.RELEASE\spring-security-rsa-1.0.3.RELEASE.jar;D:\m2_repository\org\bouncycastle\bcpkix-jdk15on\1.55\bcpkix-jdk15on-1.55.jar;D:\m2_repository\org\bouncycastle\bcprov-jdk15on\1.55\bcprov-jdk15on-1.55.jar;D:\m2_repository\org\springframework\cloud\spring-cloud-netflix-core\1.2.4.RELEASE\spring-cloud-netflix-core-1.2.4.RELEASE.jar;D:\m2_repository\org\springframework\cloud\spring-cloud-netflix-eureka-client\1.2.4.RELEASE\spring-cloud-netflix-eureka-client-1.2.4.RELEASE.jar;D:\m2_repository\com\netflix\eureka\eureka-client\1.4.12\eureka-client-1.4.12.jar;D:\m2_repository\org\codehaus\jettison\jettison\1.3.7\jettison-1.3.7.jar;D:\m2_repository\stax\stax-api\1.0.1\stax-api-1.0.1.jar;D:\m2_repository\com\netflix\netflix-commons\netflix-eventbus\0.3.0\netflix-eventbus-0.3.0.jar;D:\m2_repository\com\netflix\netflix-commons\netflix-infix\0.3.0\netflix-infix-0.3.0.jar;D:\m2_repository\commons-jxpath\commons-jxpath\1.3\commons-jxpath-1.3.jar;D:\m2_repository\joda-time\joda-time\2.9.6\joda-time-2.9.6.jar;D:\m2_repository\org\antlr\antlr-runtime\3.4\antlr-runtime-3.4.jar;D:\m2_repository\org\antlr\stringtemplate\3.2.1\stringtemplate-3.2.1.jar;D:\m2_repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;D:\m2_repository\com\google\code\gson\gson\2.7\gson-2.7.jar;D:\m2_repository\org\apache\commons\commons-math\2.2\commons-math-2.2.jar;D:\m2_repository\com\netflix\archaius\archaius-core\0.7.4\archaius-core-0.7.4.jar;D:\m2_repository\javax\ws\rs\jsr311-api\1.1.1\jsr311-api-1.1.1.jar;D:\m2_repository\com\netflix\servo\servo-core\0.10.1\servo-core-0.10.1.jar;D:\m2_repository\com\netflix\servo\servo-internal\0.10.1\servo-internal-0.10.1.jar;D:\m2_repository\com\sun\jersey\jersey-core\1.19.1\jersey-core-1.19.1.jar;D:\m2_repository\com\sun\jersey\jersey-client\1.19.1\jersey-client-1.19.1.jar;D:\m2_repository\com\sun\jersey\contribs\jersey-apache-client4\1.19.1\jersey-apache-client4-1.19.1.jar;D:\m2_repository\org\apache\httpcomponents\httpclient\4.5.2\httpclient-4.5.2.jar;D:\m2_repository\org\apache\httpcomponents\httpcore\4.4.5\httpcore-4.4.5.jar;D:\m2_repository\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;D:\m2_repository\com\google\inject\guice\4.0\guice-4.0.jar;D:\m2_repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;D:\m2_repository\com\netflix\governator\governator-api\1.12.10\governator-api-1.12.10.jar;D:\m2_repository\com\netflix\eureka\eureka-core\1.4.12\eureka-core-1.4.12.jar;D:\m2_repository\com\netflix\governator\governator\1.12.10\governator-1.12.10.jar;D:\m2_repository\com\netflix\governator\governator-core\1.12.10\governator-core-1.12.10.jar;D:\m2_repository\com\google\inject\extensions\guice-multibindings\4.0\guice-multibindings-4.0.jar;D:\m2_repository\com\google\inject\extensions\guice-grapher\4.0\guice-grapher-4.0.jar;D:\m2_repository\com\google\inject\extensions\guice-assistedinject\4.0\guice-assistedinject-4.0.jar;D:\m2_repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;D:\m2_repository\org\codehaus\woodstox\woodstox-core-asl\4.4.1\woodstox-core-asl-4.4.1.jar;D:\m2_repository\javax\xml\stream\stax-api\1.0-2\stax-api-1.0-2.jar;D:\m2_repository\org\codehaus\woodstox\stax2-api\3.1.4\stax2-api-3.1.4.jar;D:\m2_repository\org\springframework\cloud\spring-cloud-starter-archaius\1.2.4.RELEASE\spring-cloud-starter-archaius-1.2.4.RELEASE.jar;D:\m2_repository\commons-configuration\commons-configuration\1.8\commons-configuration-1.8.jar;D:\m2_repository\com\google\guava\guava\18.0\guava-18.0.jar;D:\m2_repository\com\netflix\ribbon\ribbon-eureka\2.2.0\ribbon-eureka-2.2.0.jar;D:\m2_repository\org\slf4j\slf4j-api\1.7.22\slf4j-api-1.7.22.jar;D:\m2_repository\com\thoughtworks\xstream\xstream\1.4.9\xstream-1.4.9.jar;D:\m2_repository\xmlpull\xmlpull\1.1.3.1\xmlpull-1.1.3.1.jar;D:\m2_repository\xpp3\xpp3_min\1.1.4c\xpp3_min-1.1.4c.jar;D:\m2_repository\org\springframework\cloud\spring-cloud-starter-ribbon\1.2.4.RELEASE\spring-cloud-starter-ribbon-1.2.4.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-aop\1.4.3.RELEASE\spring-boot-starter-aop-1.4.3.RELEASE.jar;D:\m2_repository\org\aspectj\aspectjweaver\1.8.9\aspectjweaver-1.8.9.jar;D:\m2_repository\org\springframework\retry\spring-retry\1.1.5.RELEASE\spring-retry-1.1.5.RELEASE.jar;D:\m2_repository\com\netflix\ribbon\ribbon\2.2.0\ribbon-2.2.0.jar;D:\m2_repository\com\netflix\ribbon\ribbon-transport\2.2.0\ribbon-transport-2.2.0.jar;D:\m2_repository\io\reactivex\rxnetty-contexts\0.4.9\rxnetty-contexts-0.4.9.jar;D:\m2_repository\io\reactivex\rxnetty-servo\0.4.9\rxnetty-servo-0.4.9.jar;D:\m2_repository\com\netflix\hystrix\hystrix-core\1.5.6\hystrix-core-1.5.6.jar;D:\m2_repository\org\hdrhistogram\HdrHistogram\2.1.9\HdrHistogram-2.1.9.jar;D:\m2_repository\javax\inject\javax.inject\1\javax.inject-1.jar;D:\m2_repository\io\reactivex\rxnetty\0.4.9\rxnetty-0.4.9.jar;D:\m2_repository\io\netty\netty-codec-http\4.0.27.Final\netty-codec-http-4.0.27.Final.jar;D:\m2_repository\io\netty\netty-codec\4.0.27.Final\netty-codec-4.0.27.Final.jar;D:\m2_repository\io\netty\netty-handler\4.0.27.Final\netty-handler-4.0.27.Final.jar;D:\m2_repository\io\netty\netty-transport-native-epoll\4.0.27.Final\netty-transport-native-epoll-4.0.27.Final.jar;D:\m2_repository\io\netty\netty-common\4.0.27.Final\netty-common-4.0.27.Final.jar;D:\m2_repository\io\netty\netty-buffer\4.0.27.Final\netty-buffer-4.0.27.Final.jar;D:\m2_repository\io\netty\netty-transport\4.0.27.Final\netty-transport-4.0.27.Final.jar;D:\m2_repository\com\netflix\ribbon\ribbon-core\2.2.0\ribbon-core-2.2.0.jar;D:\m2_repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;D:\m2_repository\com\netflix\ribbon\ribbon-httpclient\2.2.0\ribbon-httpclient-2.2.0.jar;D:\m2_repository\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;D:\m2_repository\com\netflix\netflix-commons\netflix-commons-util\0.1.1\netflix-commons-util-0.1.1.jar;D:\m2_repository\com\netflix\ribbon\ribbon-loadbalancer\2.2.0\ribbon-loadbalancer-2.2.0.jar;D:\m2_repository\com\netflix\netflix-commons\netflix-statistics\0.1.1\netflix-statistics-0.1.1.jar;D:\m2_repository\io\reactivex\rxjava\1.1.10\rxjava-1.1.10.jar;D:\m2_repository\org\springframework\spring-core\4.3.5.RELEASE\spring-core-4.3.5.RELEASE.jar;D:\idea\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar" com.itmuch.cloud.microserviceconsumermovieribbon.MicroserviceConsumerMovieRibbonApplication
Connected to the target VM, address: '127.0.0.1:56625', transport: 'socket'
2019-10-25 11:31:04.536  INFO 22436 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@41ab013: startup date [Fri Oct 25 11:31:04 CST 2019]; root of context hierarchy
2019-10-25 11:31:04.873  INFO 22436 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2019-10-25 11:31:04.920  INFO 22436 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [class org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$cf0a7647] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.3.RELEASE)

2019-10-25 11:31:05.373  INFO 22436 --- [           main] croserviceConsumerMovieRibbonApplication : No active profile set, falling back to default profiles: default
2019-10-25 11:31:05.389  INFO 22436 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@138a7441: startup date [Fri Oct 25 11:31:05 CST 2019]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@41ab013
2019-10-25 11:31:06.076  WARN 22436 --- [           main] o.s.c.a.ConfigurationClassPostProcessor  : Cannot enhance @Configuration bean definition 'refreshScope' since its singleton instance has been created too early. The typical cause is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as 'static'.
2019-10-25 11:31:06.185  INFO 22436 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=e550db78-c83c-3c42-8451-90eed13f1417
2019-10-25 11:31:06.248  INFO 22436 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2019-10-25 11:31:06.420  INFO 22436 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.netflix.metrics.MetricsInterceptorConfiguration$MetricsRestTemplateConfiguration' of type [class org.springframework.cloud.netflix.metrics.MetricsInterceptorConfiguration$MetricsRestTemplateConfiguration$$EnhancerBySpringCGLIB$$e51d198b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-10-25 11:31:06.420  INFO 22436 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [class org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$cf0a7647] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-10-25 11:31:06.701  INFO 22436 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8010 (http)
2019-10-25 11:31:06.717  INFO 22436 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2019-10-25 11:31:06.717  INFO 22436 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2019-10-25 11:31:06.826  INFO 22436 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-10-25 11:31:06.826  INFO 22436 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1437 ms
2019-10-25 11:31:07.076  INFO 22436 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2019-10-25 11:31:07.076  INFO 22436 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'metricsFilter' to: [/*]
2019-10-25 11:31:07.076  INFO 22436 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2019-10-25 11:31:07.076  INFO 22436 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2019-10-25 11:31:07.076  INFO 22436 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2019-10-25 11:31:07.076  INFO 22436 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2019-10-25 11:31:07.076  INFO 22436 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2019-10-25 11:31:07.076  INFO 22436 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'applicationContextIdFilter' to: [/*]
2019-10-25 11:31:07.779  INFO 22436 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@138a7441: startup date [Fri Oct 25 11:31:05 CST 2019]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@41ab013
2019-10-25 11:31:07.857  INFO 22436 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/user/{id}],methods=[GET]}" onto public com.itmuch.cloud.microserviceconsumermovieribbon.entity.User com.itmuch.cloud.microserviceconsumermovieribbon.controller.MovieController.findById(java.lang.Long)
2019-10-25 11:31:07.857  INFO 22436 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/log-instance],methods=[GET]}" onto public void com.itmuch.cloud.microserviceconsumermovieribbon.controller.MovieController.logUserInstance()
2019-10-25 11:31:07.857  INFO 22436 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2019-10-25 11:31:07.857  INFO 22436 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2019-10-25 11:31:07.904  INFO 22436 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-10-25 11:31:07.904  INFO 22436 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-10-25 11:31:07.935  INFO 22436 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/resume || /resume.json],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.endpoint.GenericPostableMvcEndpoint.invoke()
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/refresh || /refresh.json],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.endpoint.GenericPostableMvcEndpoint.invoke()
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/archaius || /archaius.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/features || /features.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.404  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/restart || /restart.json],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.context.restart.RestartMvcEndpoint.invoke()
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health || /health.json],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/info || /info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/pause || /pause.json],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.endpoint.GenericPostableMvcEndpoint.invoke()
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.context.environment.EnvironmentManagerMvcEndpoint.value(java.util.Map<java.lang.String, java.lang.String>)
2019-10-25 11:31:08.419  INFO 22436 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env/reset],methods=[POST]}" onto public java.util.Map<java.lang.String, java.lang.Object> org.springframework.cloud.context.environment.EnvironmentManagerMvcEndpoint.reset()
2019-10-25 11:31:08.560  WARN 22436 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
2019-10-25 11:31:08.560  INFO 22436 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2019-10-25 11:31:08.560  WARN 22436 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
2019-10-25 11:31:08.560  INFO 22436 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2019-10-25 11:31:08.732  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2019-10-25 11:31:08.747  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'refreshScope' has been autodetected for JMX exposure
2019-10-25 11:31:08.747  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'environmentManager' has been autodetected for JMX exposure
2019-10-25 11:31:08.747  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'configurationPropertiesRebinder' has been autodetected for JMX exposure
2019-10-25 11:31:08.747  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'refreshEndpoint' has been autodetected for JMX exposure
2019-10-25 11:31:08.747  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'restartEndpoint' has been autodetected for JMX exposure
2019-10-25 11:31:08.747  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'environmentManager': registering with JMX server as MBean [org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager]
2019-10-25 11:31:08.763  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'restartEndpoint': registering with JMX server as MBean [org.springframework.cloud.context.restart:name=restartEndpoint,type=RestartEndpoint]
2019-10-25 11:31:08.763  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'refreshScope': registering with JMX server as MBean [org.springframework.cloud.context.scope.refresh:name=refreshScope,type=RefreshScope]
2019-10-25 11:31:08.779  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'configurationPropertiesRebinder': registering with JMX server as MBean [org.springframework.cloud.context.properties:name=configurationPropertiesRebinder,context=138a7441,type=ConfigurationPropertiesRebinder]
2019-10-25 11:31:08.794  INFO 22436 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'refreshEndpoint': registering with JMX server as MBean [org.springframework.cloud.endpoint:name=refreshEndpoint,type=RefreshEndpoint]
2019-10-25 11:31:08.919  INFO 22436 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2019-10-25 11:31:08.935  INFO 22436 --- [           main] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2019-10-25 11:31:09.357  INFO 22436 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON encoding codec LegacyJacksonJson
2019-10-25 11:31:09.357  INFO 22436 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON decoding codec LegacyJacksonJson
2019-10-25 11:31:09.435  INFO 22436 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using XML encoding codec XStreamXml
2019-10-25 11:31:09.435  INFO 22436 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using XML decoding codec XStreamXml
2019-10-25 11:31:09.638  INFO 22436 --- [           main] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2019-10-25 11:31:09.732  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
2019-10-25 11:31:09.732  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
2019-10-25 11:31:09.732  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
2019-10-25 11:31:09.732  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
2019-10-25 11:31:09.732  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
2019-10-25 11:31:09.732  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
2019-10-25 11:31:09.732  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
2019-10-25 11:31:09.888  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : The response status is 200
2019-10-25 11:31:09.903  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Starting heartbeat executor: renew interval is: 30
2019-10-25 11:31:09.903  INFO 22436 --- [           main] c.n.discovery.InstanceInfoReplicator     : InstanceInfoReplicator onDemand update allowed rate per min is 4
2019-10-25 11:31:09.903  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1571974269903 with initial instances count: 3
2019-10-25 11:31:09.919  INFO 22436 --- [           main] c.n.e.EurekaDiscoveryClientConfiguration : Registering application microservice-consumer-movie with eureka with status UP
2019-10-25 11:31:09.919  INFO 22436 --- [           main] com.netflix.discovery.DiscoveryClient    : Saw local status change event StatusChangeEvent [timestamp=1571974269919, current=UP, previous=STARTING]
2019-10-25 11:31:09.919  INFO 22436 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_MICROSERVICE-CONSUMER-MOVIE/DESKTOP-3NP6QV0:microservice-consumer-movie:8010: registering service...
2019-10-25 11:31:09.966  INFO 22436 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_MICROSERVICE-CONSUMER-MOVIE/DESKTOP-3NP6QV0:microservice-consumer-movie:8010 - registration status: 204
2019-10-25 11:31:10.013  INFO 22436 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8010 (http)
2019-10-25 11:31:10.013  INFO 22436 --- [           main] c.n.e.EurekaDiscoveryClientConfiguration : Updating port to 8010
2019-10-25 11:31:10.013  INFO 22436 --- [           main] croserviceConsumerMovieRibbonApplication : Started MicroserviceConsumerMovieRibbonApplication in 6.398 seconds (JVM running for 7.492)
2019-10-25 11:32:40.024  INFO 22436 --- [nio-8010-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-10-25 11:32:40.024  INFO 22436 --- [nio-8010-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2019-10-25 11:32:40.055  INFO 22436 --- [nio-8010-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 31 ms
2019-10-25 11:32:40.086  INFO 22436 --- [nio-8010-exec-1] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ce5c0d6: startup date [Fri Oct 25 11:32:40 CST 2019]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@138a7441
2019-10-25 11:32:40.118  INFO 22436 --- [nio-8010-exec-1] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2019-10-25 11:32:40.305  INFO 22436 --- [nio-8010-exec-1] c.netflix.config.ChainedDynamicProperty  : Flipping property: microservice-provider-user.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-10-25 11:32:40.321  INFO 22436 --- [nio-8010-exec-1] c.n.u.concurrent.ShutdownEnabledTimer    : Shutdown hook installed for: NFLoadBalancer-PingTimer-microservice-provider-user
2019-10-25 11:32:40.352  INFO 22436 --- [nio-8010-exec-1] c.netflix.loadbalancer.BaseLoadBalancer  : Client:microservice-provider-user instantiated a LoadBalancer:DynamicServerListLoadBalancer:{NFLoadBalancer:name=microservice-provider-user,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2019-10-25 11:32:40.352  INFO 22436 --- [nio-8010-exec-1] c.n.l.DynamicServerListLoadBalancer      : Using serverListUpdater PollingServerListUpdater
2019-10-25 11:32:40.383  INFO 22436 --- [nio-8010-exec-1] c.netflix.config.ChainedDynamicProperty  : Flipping property: microservice-provider-user.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-10-25 11:32:40.383  INFO 22436 --- [nio-8010-exec-1] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client microservice-provider-user initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=microservice-provider-user,current list of Servers=[192.168.1.143:8000, 192.168.1.143:8001],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;	Instance count:2;	Active connections count: 0;	Circuit breaker tripped count: 0;	Active connections per server: 0.0;]
},Server stats: [[Server:192.168.1.143:8000;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
, [Server:192.168.1.143:8001;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@14b71fb8
2019-10-25 11:32:40.477  INFO 22436 --- [nio-8010-exec-1] c.i.c.m.controller.MovieController       : microservice-provider-user:192.168.1.143:8000
2019-10-25 11:32:41.368  INFO 22436 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: microservice-provider-user.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-10-25 11:32:41.789  INFO 22436 --- [nio-8010-exec-3] c.i.c.m.controller.MovieController       : microservice-provider-user:192.168.1.143:8001
2019-10-25 11:32:41.977  INFO 22436 --- [nio-8010-exec-4] c.i.c.m.controller.MovieController       : microservice-provider-user:192.168.1.143:8000
2019-10-25 11:32:42.164  INFO 22436 --- [nio-8010-exec-5] c.i.c.m.controller.MovieController       : microservice-provider-user:192.168.1.143:8001
2019-10-25 11:32:42.320  INFO 22436 --- [nio-8010-exec-6] c.i.c.m.controller.MovieController       : microservice-provider-user:192.168.1.143:8000
2019-10-25 11:32:42.492  INFO 22436 --- [nio-8010-exec-7] c.i.c.m.controller.MovieController       : microservice-provider-user:192.168.1.143:8001
2019-10-25 11:32:42.664  INFO 22436 --- [nio-8010-exec-8] c.i.c.m.controller.MovieController       : microservice-provider-user:192.168.1.143:8000
2019-10-25 11:32:42.836  INFO 22436 --- [nio-8010-exec-9] c.i.c.m.controller.MovieController       : microservice-provider-user:192.168.1.143:8001

使用java代码自定义Ribbon配置

microservice-consumer-movie-ribbon项目

依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.itmuch.cloud</groupId>
    <artifactId>microservice-consumer-movie-ribbon</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>microservice-consumer-movie-ribbon</name>
    <description>Demo project for Spring Boot</description>


    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <!--引入spring cloud依赖-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR4</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>

</project>

yml

server:
  port: 8010
spring:
  application:
    name: microservice-consumer-movie
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
  instance:
    prefer-ip-address: true

启动类

package com.itmuch.cloud.microserviceconsumermovieribbon;

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.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class MicroserviceConsumerMovieRibbonApplication {

    /**
     * 实例化一个Bean并使用该方法的名字命名
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(MicroserviceConsumerMovieRibbonApplication.class, args);
    }

}

实体类

package com.itmuch.cloud.microserviceconsumermovieribbon.entity;

import java.math.BigDecimal;

public class User {
    private Long id;
    private String username;
    private String name;
    private Integer age;
    private BigDecimal balance;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public BigDecimal getBalance() {
        return balance;
    }

    public void setBalance(BigDecimal balance) {
        this.balance = balance;
    }
}

controller

package com.itmuch.cloud.microserviceconsumermovieribbon.controller;

import com.itmuch.cloud.microserviceconsumermovieribbon.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class MovieController {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    private static final Logger logger = LoggerFactory.getLogger(MovieController.class);

    /**
     * microservice-provider-user:虚拟主机名
     * @param id
     * @return
     */
    @GetMapping("/user/{id}")
    public User findById(@PathVariable Long id){
        return this.restTemplate.getForObject("http://microservice-provider-user/" + id,User.class);
    }

    @GetMapping("/log-instance")
    public void logUserInstance(){
        ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
        //打印当前选择的那个节点
        MovieController.logger.info("{}:{}:{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
    }
}

复制项目microservice-consumer-movie-ribbon,将ArtifactId修改为microservice-consumer-movie-ribbon-customizing

创建Ribbon的配置类

package com.itmuch.cloud.microserviceconsumermovieribboncustomizing.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RibbonConfiguration {
    /**
     * BeanType是IRule
     * beanName是ribbonRule
     * ClassName是ZoneAvoidanceRule
     * @return
     */
    @Bean
    public IRule ribbonRule(){
        //负载均衡规则,改为随机
        return new RandomRule();
    }
}

创建一个空类,并在其添加上@Configuration注解和@RibbonClient注解

package com.itmuch.cloud.microserviceconsumermovieribboncustomizing.config;

import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;

/**
 * 使用@RibbonClient,为特定name的Ribbon Client自定义配置
 * 使用@RibbonClient的configuration属性,指定Ribbon的配置类
 */
@Configuration
@RibbonClient(name = "microservice-provider-user",configuration = RibbonConfiguration.class)
public class TestConfiguration {

}

启动测试

使用属性自定义Ribbon配置

复制项目microservice-consumer-movie-ribbon,将ArtifactId修改为microservice-consumer-movie-ribbon-customizing-properties

只需要在yml中添加如下即可

microservice-provider-user:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

测试结果

脱离Eureka使用Ribbon

Ribbon支持脱离Eureka使用,架构图如下

复制项目microservice-consumer-movie-ribbon,将ArtifactId修改为microservice-consumer-movie-ribbon-wirhout-eureka

我们去掉Eureka的依赖spring-cloud-starter-eureka,只使用Ribbon的依赖spring-cloud-starter-ribbon

     <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

去掉启动类上的@EnableDiscoveryClient注解

将application.yml改成如下

server:
  port: 8010
spring:
  application:
    name: microservice-consumer-movie
microservice-provider-user:
  ribbon:
    listOfServers: localhost:8000,localhost:8001

2019-10-25 14:21:40.638  INFO 9160 --- [nio-8010-exec-1] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8000
2019-10-25 14:21:41.279  INFO 9160 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: microservice-provider-user.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-10-25 14:21:41.825  INFO 9160 --- [nio-8010-exec-2] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8001
2019-10-25 14:21:42.967  INFO 9160 --- [nio-8010-exec-3] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8000
2019-10-25 14:21:43.655  INFO 9160 --- [nio-8010-exec-4] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8001
2019-10-25 14:21:43.858  INFO 9160 --- [nio-8010-exec-5] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8000
2019-10-25 14:21:44.030  INFO 9160 --- [nio-8010-exec-6] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8001
2019-10-25 14:21:44.201  INFO 9160 --- [nio-8010-exec-7] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8000
2019-10-25 14:21:44.389  INFO 9160 --- [nio-8010-exec-8] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8001
2019-10-25 14:21:44.686  INFO 9160 --- [nio-8010-exec-9] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8000
2019-10-25 14:21:44.873  INFO 9160 --- [io-8010-exec-10] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8001
2019-10-25 14:21:45.045  INFO 9160 --- [nio-8010-exec-1] c.i.c.m.controller.MovieController       : microservice-provider-user:localhost:8000

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值