spring cloud 构建微服务二(eureka)服务注册中心的高可用性、服务调用、负载均衡

前一篇文章写了如何使用eureka来进行服务的注册与发现。这篇记录下,如何使用 eureka进行服务注册中心的高可用性、服务调用、负载均衡。

  • 先看一下配置表。
应用名称 eureka-server eureka-service eureka-customer
端口 9000-9099 9100-9199 9200-9299
说明 提供注册服务 服务本身 消费服务
初始化3个eureka-server项目
  • 如何初始化项目,使用的注解等这里就不写了,在第一篇里有。其三个项目的配置文件分别为:
# 服务注册中心
spring.application.name=eureka-server
server.port=9000

#####################################
### eureka 实例配置###################
#####################################
eureka.instance.hostname=eureka-server0
# eureka 客户端(发布的业务服务)向 eureka 服务中心发送心跳,表示该客户端依然存在,
# 如果在 leaseExpirationDurationInSeconds 时间内没有收到心跳,则服务中心会把实例从视图移除
eureka.instance.lease-renewal-interval-in-seconds=4
# 发送心跳时,等待接收心跳的最大时间。该值应该大于 leaseRenewalIntervalInSeconds
# 如果该值太大,则很可能将流量转发过去的时候,该实例已不可用
# 如果该值太小,则实例很可能因为临时的网络抖动而被移除
eureka.instance.lease-expiration-duration-in-seconds=6

#####################################
### eureka 客户端配置(发布的业务服务)##
#####################################
# 间隔多久后,从 eureka 服务中心上更新注册自己的业务服务
eureka.client.registry-fetch-interval-seconds=5
# eureka 服务中心的地址
eureka.client.serviceUrl.defaultZone=http://eureka-server1:9001/eureka/,http://eureka-server2:9002/eureka/

#####################################
### eureka 服务端配置#################
#####################################
# 清理间隔(单位毫秒,默认是0 不清除)
eureka.server.eviction-interval-timer-in-ms=3000
# 服务注册中心
spring.application.name=eureka-server
server.port=9001

#####################################
### eureka 实例配置###################
#####################################
eureka.instance.hostname=eureka-server1
# eureka 客户端(发布的业务服务)向 eureka 服务中心发送心跳,表示该客户端依然存在,
# 如果在 leaseExpirationDurationInSeconds 时间内没有收到心跳,则服务中心会把实例从视图移除
eureka.instance.lease-renewal-interval-in-seconds=4
# 发送心跳时,等待接收心跳的最大时间。该值应该大于 leaseRenewalIntervalInSeconds
# 如果该值太大,则很可能将流量转发过去的时候,该实例已不可用
# 如果该值太小,则实例很可能因为临时的网络抖动而被移除
eureka.instance.lease-expiration-duration-in-seconds=6

#####################################
### eureka 客户端配置(发布的业务服务)##
#####################################
# 间隔多久后,从 eureka 服务中心上更新注册自己的业务服务
eureka.client.registry-fetch-interval-seconds=5
# eureka 服务中心的地址
eureka.client.serviceUrl.defaultZone=http://eureka-server0:9000/eureka/,http://eureka-server2:9002/eureka/

#####################################
### eureka 服务端配置#################
#####################################
# 清理间隔(单位毫秒,默认是0 不清除)
eureka.server.eviction-interval-timer-in-ms=3000
# 服务注册中心
spring.application.name=eureka-server
server.port=9002

#####################################
### eureka 实例配置###################
#####################################
eureka.instance.hostname=eureka-server2
# eureka 客户端(发布的业务服务)向 eureka 服务中心发送心跳,表示该客户端依然存在,
# 如果在 leaseExpirationDurationInSeconds 时间内没有收到心跳,则服务中心会把实例从视图移除
eureka.instance.lease-renewal-interval-in-seconds=4
# 发送心跳时,等待接收心跳的最大时间。该值应该大于 leaseRenewalIntervalInSeconds
# 如果该值太大,则很可能将流量转发过去的时候,该实例已不可用
# 如果该值太小,则实例很可能因为临时的网络抖动而被移除
eureka.instance.lease-expiration-duration-in-seconds=6

#####################################
### eureka 客户端配置(发布的业务服务)##
#####################################
# 间隔多久后,从 eureka 服务中心上更新注册自己的业务服务
eureka.client.registry-fetch-interval-seconds=5
# eureka 服务中心的地址
eureka.client.serviceUrl.defaultZone=http://eureka-server0:9000/eureka/,http://eureka-server1:9001/eureka/

#####################################
### eureka 服务端配置#################
#####################################
# 清理间隔(单位毫秒,默认是0 不清除)
eureka.server.eviction-interval-timer-in-ms=3000
  • 之后分别启动这三个eureka-server注册服务中心项目。
    启动后会看到有三个可用的服务注册中心
初始化2个eureka-service项目
  • 如何初始化项目、使用的注解等这里就不写了,在第一篇里有。2个项目的配置文件分别为:
# 服务提供者
spring.application.name=eureka-service
server.port=9100

# eureka 服务中心的地址
eureka.client.serviceUrl.defaultZone=http://eureka-server0:9000/eureka/,http://eureka-server1:9001/eureka/,http://eureka-server2:9002/eureka/
# 服务提供者
spring.application.name=eureka-service
server.port=9101

# eureka 服务中心的地址
eureka.client.serviceUrl.defaultZone=http://eureka-server0:9000/eureka/,http://eureka-server1:9001/eureka/,http://eureka-server2:9002/eureka/
  • 启动这两个项目


    启动后服务注册中心已经发现了这两个业务服务
创建服务消费者
  • 项目配置文件为:
# 服务消费者
spring.application.name=eureka-customer
server.port=9200

# eureka 服务中心的地址
eureka.client.serviceUrl.defaultZone=http://eureka-server0:9000/eureka/,http://eureka-server1:9001/eureka/,http://eureka-server2:9002/eureka/
  • EurekaCustomerApplication.java
package com.zb.eurekacustomer;

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

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaCustomerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaCustomerApplication.class, args);
    }
}
  • RestConfig.java 使用RestTemplate发起真实的rest请求
package com.zb.eurekacustomer.config;

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

/**
 * @author 张博
 */
@Configuration
public class RestConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
  • UserCustomerController.java LoadBalancerClientspring cloud提供的一个客户端负责均衡器。作用是时流量均衡流向每一个服务。
package com.zb.eurekacustomer.c_user.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author 张博
 */
@RestController
public class UserCustomerController {

    private LoadBalancerClient loadBalancerClient;
    private RestTemplate restTemplate;

    @Autowired
    private UserCustomerController(LoadBalancerClient loadBalancerClient, RestTemplate restTemplate) {
        this.loadBalancerClient = loadBalancerClient;
        this.restTemplate = restTemplate;
    }

    @RequestMapping(value = "/getServices", method = RequestMethod.GET)
    public String getServices() {
        // 从 LoadBalancer 中为指定的业务服务选择业务服务实例
        ServiceInstance serviceInstance = loadBalancerClient.choose("eureka-service");
        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/getServices/" + serviceInstance.getPort();
        System.out.println(url);
        return restTemplate.getForObject(url, String.class);
    }
}

  • 启动项目


    启动后可以发现服务消费者出现在了服务注册中心
演示
  • 服务调用
    在浏览器中输入 http://127.0.0.1:9200/getServices

    发现可用调用远程的服务

  • 负载均衡
    在浏览器中多次刷新http://127.0.0.1:9200/getServices

    可以发现负载均衡可以正常使用,流量被均摊

  • 注册中心的高可用性
    我们停掉端口为9001注册中心

    发现端口为9001不在了

不可用的服务
  • 这时我们发布新的业务服务。发现还是可以正常使用。

推荐阅读更多精彩内容