(三)Spring Cloud Ribbon 实现服务访问的负载均衡

本章将讲解通过Ribbon实现负载均衡去访问多台Eureka Client中的服务

本项目是一个独立的maven项目,其中的多个module。

 Eureka-Server,Eureka-Client ,Eureka-Ribbon_Client模块,其中Eureka-Client后续会以2个端口启动,并分别在Eureka-Server注册

 

1. 新建一个maven项目eureka-ribbon

2. 新建一个eureka-server

 具体配置和上一篇类似

   2.1 pom文件

 

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</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>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <scope>compile</scope>
        </dependency>

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

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

   2.2 启动类

  

package com.devin.eurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;


@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

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

}

 

   2.3 安全校验

   

package com.devin.eurekaserver.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭csrf
        super.configure(http);
        //开启认证
        http.csrf().disable();
    }
}

 

  2.4 application.yml配置文件

   eureka-server的启动端口为 7001

server:
  port: 7001 #启动端口
spring:
  #应用名称
  application:
    name: eureka-server
  #安全配置
  security:
    basic:
      enabled: true
    user:
      name: dev
      password: 123456

#eureka配置
eureka:
  server:
    #设置扫描失效服务的间隔时间
    eviction-interval-timer-in-ms: 20000
    enable-self-preservation: true
  instance:
    hostname: localhost
    leaseRenewalIntervalInSeconds: 10
    health-check-url-path: /actuator/health
  client:
    register-with-eureka: false  #false:不作为一个客户端注册到注册中心
    fetch-registry: false        #为true时,可以启动,但报异常:Cannot execute request on any known server
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

# health endpoint是否必须显示全部细节。默认情况下, /actuator/health 是公开的,并且不显示细节。
# 设置actuator开关
management:
  security:
    enabled: false
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

 

  3. 创建eureka-client

    eureka client后续将启动两个端口7002,7003,并分别在eureka-server注册

      3.1 pom文件

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.8.RELEASE</version>
        </dependency>

 

     3.2 启动类

   

package com.devin.eurekaclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {

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

}

  

     3.3 新建一个Controller类,该类打印出eureka-client的启动端口

   

package com.devin.eurekaclient.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Devin Zhang
 * @className HelloController
 * @description TODO
 * @date 2020/3/28 10:45
 */

@RestController
public class HelloController {

    @Value("${server.port}")
    private Integer port;

    @GetMapping("/sayHello")
    public String sayHello(String name) {
        return "Hello ," + name + " ,this response is from eureka client port:" + port;
    }
}

  

     3.4  application.yml 配置文件

 

eureka:
  auth:
    user: dev
    password: 123456
  client:
    serviceUrl:
      defaultZone: http://${eureka.auth.user}:${eureka.auth.password}@localhost:7001/eureka/
  instance:
    #使用IP进行注册
    prefer-ip-address: true
    #配置实例的注册ID
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    #心跳时间,即服务续约间隔时间(缺省为30s)
    lease-renewal-interval-in-seconds: 5
    #发呆时间,即服务续约到期时间(缺省为90s)
    lease-expiration-duration-in-seconds: 10
    health-check-url-path: /actuator/health
server:
  port: 7002
spring:
  application:
    name: eureka-client

 

 启动eureka-client,分别在两个端口启动,这两个eureka-client实例将分别向 7001 eureka-server进行注册

 java -jar eureka-client-0.0.1-SNAPSHOT.jar --server.port=7002

 java -jar eureka-client-0.0.1-SNAPSHOT.jar --server.port=7003

 

 4.  eureka-client-ribbon 

  该服务将做为一个eureka-client进行注册,并通过RestTemplate对eureka-client进行负载均衡访问

      4.1  pom.xml

    

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.8.RELEASE</version>
        </dependency>

    4.2 启动类

    

package com.devin.eurekaribbonclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class EurekaRibbonClientApplication {

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

}

  

      4.3 RestTemplate 配置类,支持负载均衡

 

package com.devin.eurekaribbonclient.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author Devin Zhang
 * @className RibbonConfig
 * @description TODO
 * @date 2020/3/28 11:51
 */
@Configuration
public class RibbonConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

  

    4.4  新建Service类,通过RestTemplate,负载均衡调用eureka-client的接口

     

package com.devin.eurekaribbonclient.service;

import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author Devin Zhang
 * @className RibbonHelloService
 * @description TODO
 * @date 2020/3/28 11:54
 */
@Service
public class RibbonHelloService {

    @Resource
    private RestTemplate restTemplate;

    public String sayHello(String name) {
        return restTemplate.getForObject("http://EUREKA-CLIENT/sayHello?name=" + name, String.class);
    }
}

  

       4.5  Controller入口类,用于测试

    

package com.devin.eurekaribbonclient.controller;

import com.devin.eurekaribbonclient.service.RibbonHelloService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author Devin Zhang
 * @className RibbonHelloController
 * @description TODO
 * @date 2020/3/28 11:57
 */
@RestController
public class RibbonHelloController {

    @Resource
    private RibbonHelloService ribbonHelloService;

    @GetMapping("/sayHelloFromRibbon")
    public String sayHello(String name) {
        return ribbonHelloService.sayHello(name);
    }
}

  

  4.6  application.yml 配置文件

  

eureka:
  auth:
    user: dev
    password: 123456
  client:
    serviceUrl:
      defaultZone: http://${eureka.auth.user}:${eureka.auth.password}@localhost:7001/eureka/
  instance:
    #使用IP进行注册
    prefer-ip-address: true
    #配置实例的注册ID
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    #心跳时间,即服务续约间隔时间(缺省为30s)
    lease-renewal-interval-in-seconds: 5
    #发呆时间,即服务续约到期时间(缺省为90s)
    lease-expiration-duration-in-seconds: 10
    health-check-url-path: /actuator/health
server:
  port: 7004
spring:
  application:
    name: eureka-ribbon-client

 

5. 测试结果

 分别启动

  eureka-server 7001

  eureka-client 7002

  eureka-client 7003

  eureka-ribbon-client 7004

 

在注册中心http://localhost:7001可以看到,各个客户端已经进行了注册

 

 

 

验证负载均衡,访问 http://localhost:7004/sayHelloFromRibbon?name=devin   ,可以看到对eureka-client的访问,会负载均衡到 7002,7003 对应的实例

 

 

 

 

 

 

posted @ 2020-03-28 15:07  devin_w_zhang  阅读(209)  评论(0编辑  收藏  举报