Eureka

Eureka使用步骤

  • eureka服务端
  1. 添加eureka-server依赖坐标
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  1. eureka-server配置项
server:
  port: 9001
spring:
  application:
    name: eureka-service

eureka:
  client:
    register-with-eureka: false #是否将自己注册到注册中心,单机服务可以不开启
    fetch-registry: false #是否从注册中心拉取数据,单机服务可以不开启
    #暴露给Eureka Client的请求地址
    service-url:
      defaultZone: http://127.0.0.1:9001/eureka/
  1. 修改启动类注解
@EnableEurekaServer
 @SpringBootApplication
 public class EurekaServiceApplication {
     public static void main(String[] args) {
         SpringApplication.run(EurekaServiceApplication.class, args);
     }
 }
  • 服务提供方
  1. 添加eureka-client依赖坐标
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>
  1. 添加配置项
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9001/eureka/
  1. 修改启动类注解
//激活EurekaClient
//@EnableEurekaClient
//或者使用@EnableDiscoveryClient,当配置了defaultZone时,即使不开启注解也会自从注册的eureka注册中心
@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("com.cloud.userservice.mapper")
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}
  • 服务消费方
    1、2、3、与服务提供方类似
    4、在调用服务的地方修改获取服务提供方地址方式
//自动注入DiscoveryClient
    @Autowired
    DiscoveryClient discoveryClient;

    @GetMapping("/getUserById/{id}")
    public User getUserById(@PathVariable Long id){
        String url = "http://localhost:8001/user/getUserById/"+id;
        //根据服务注册名称获取服务实例列表
        List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
        ServiceInstance serviceInstance = instances.get(0);
        //获取服务的ip+port
        url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/user/getUserById/"+id;
        return restTemplate.getForObject(url,User.class);
    }

Eureka高可用

配置多台eureka-server,开启发现注册和拉取服务,互相注册

server:
  port: 9001
spring:
  application:
    name: eureka-service
    
eureka:
  client:
    #暴露给Eureka Client的请求地址
    service-url:
      defaultZone: http://127.0.0.1:9002/eureka/,http://127.0.0.1:9003/eureka/
server:
  port: 9002
spring:
  application:
    name: eureka-service
    
eureka:
  client:
    #暴露给Eureka Client的请求地址
    service-url:
      defaultZone: http://127.0.0.1:9001/eureka/,http://127.0.0.1:9003/eureka/
server:
  port: 9003
spring:
  application:
    name: eureka-service
    
eureka:
  client:
    #暴露给Eureka Client的请求地址
    service-url:
      defaultZone: http://127.0.0.1:9001/eureka/,http://127.0.0.1:9002/eureka/

Eureka细节问题

在控制台显示服务IP

配置使用ip地址和并向注册中心注册ip地址

eureka:
  client:
    service-url:
      defaultZone: http://localhost:9001/eureka/
  instance:
    prefer-ip-address: true #使用ip地址注册
    instance-id: ${spring.cloud.client.ip-address}:${port} #向注册中心注册服务id

Eureka的服务剔除问题

服务的提供者,设置心跳间隔和续约到期时间

eureka:
  client:
    service-url:
      defaultZone: http://localhost:9001/eureka/
  instance:
    prefer-ip-address: true #使用ip地址注册
    instance-id: ${spring.cloud.client.ip-address}:${port} #向注册中心注册服务id
    lease-renewal-interval-in-seconds: 5  #发送心跳间隔,默认30秒
    lease-expiration-duration-in-seconds: 10 #续约到期时间,默认90秒

Eureka的自我保护机制

开发阶段可在eureka-server中配置关闭自我保护和服务剔除时间

server:
    enable-self-preservation: false #是否开启自我保护机制 默认true
    eviction-interval-timer-in-ms: 4000 #服务宕机后多久剔除服务

consul

1 安装启动

进入consul的安装目录

##以开发者模式快速启动
consul agent -dev -client=0.0.0.0
agent:启动一个consul的守护进程
	dev:开发者模式
	client:是consul代理,和consul server交互
        可以有多个
        一个微服务对应一个client
        微服务和client部署到同一台机器上
	server:真正工作的consul服务
		官方推荐3-5个
		
		
Gossip:流言协议
	所有的consul节点都会参与到gossip协议中(多节点中数据赋值)

服务端Raft协议:	http://thesecretlivesofdata.com/raft/ (可视化算法流程图)
	保证server集群的数据一致
		Leader:是server集群中唯一处理客户端请求的
		Follower:选民,被动接受数据
		候选人:可以被选举为Leader

进入到管理后台界面

http://{{ip}}:8500

2 入门案例

  1. 提供一个服务者微服务
  2. 提供一个消费者服务
  3. 将微服务注册到注册中心consul
  • 依赖
<!-- springcloud提供的基于consul的服务发现-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    <version>2.2.0.RELEASE</version>
</dependency>
<!-- actuator健康检查 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • 配置
#配置consul的服务注册
  cloud:
    consul:
      host: 127.0.0.1 #consul服务器的主机地址
      port: 8500  #consul服务器的端口地址
      discovery:
        register: true #是否需要注册
        instance-id: ${spring.application.name}-${server.port} #注册的实例ID(唯一标志)
        service-name: ${spring.application.name} #服务的名称
        port: ${server.port} #服务的请求端口
        prefer-ip-address: true #指定开启ip地址注册
        ip-address: ${spring.cloud.client.ip-address}#当前服务的请求ip
  1. 服务的消费者从consul中拉取所有的服务列表
  • 依赖和配置同上
  • 对RestTemplate bean添加@LoadBalanced注解
/**
   * springcloud 对consul进行了进一步的处理
   * 向其中集成了ribbon的支持
   * @return
  */
  @Bean
  @LoadBalanced
  public RestTemplate restTemplate(){
      return new RestTemplate();
  }
  • Controller调用端中继续使用服务名发起请求
@GetMapping("/getUserById/{id}")
public User getUserById(@PathVariable Long id) {
    String url = "http://user-service/user/getUserById/"+id;
    return restTemplate.getForObject(url, User.class);
}

3 consule高可用集群

  1. 下载安装consul
  • 下载后解压
  • 移动至/usr/local/bin
  • 使用consul命令测试
  1. 启动每个consul server节点
## 登录s1服务器,以server形式运行
consul agent -server -bootstrap-expect 3 -data-dir /etc/consul.d -node=server-1 -bind=192.168.74.101 -ui -client 0.0.0.0 &
## 登录s2服务器,以server形式运行
consul agent -server -bootstrap-expect 2 -data-dir /etc/consul.d -node=server-2 -bind=192.168.74.102 -ui -client 0.0.0.0 &
## 登录s3服务器,以server形式运行
consul agent -server -bootstrap-expect 2 -data-dir /etc/consul.d -node=server-3 -bind=192.168.74.103 -ui -client 0.0.0.0 &

-server:以server身份启动

-bootstrap-expect:集群要求的最少server数量,当低于这个数量,集群即失效。

-data-dir:data存放的目录,更多信息请参阅consul数据同步机制

-node:节点id,在同一集群中不能重复

-bind:监听的ip地址

-ui:打开web监控页面

-client:客户端的ip地址(0.0.0.0表示不限制)

&:后台运行

  1. 三个consul server模式服务全部启动完成
##在本地电脑上使用client形式启动consul
consul agent -client=0.0.0.0 -bind=192.168.74.1 -data-dir /etc/consul.d -node=client-1
  1. 每个节点加入集群
    在s2、s3、s4服务器上通过consul join命令加入s1的consul中
## 加入consul集群
consul join 192.168.74.101
  1. 在任意一台服务器中输入consul members查看集群中的所有节点信息
##查看consul集群节点信息
consul members

4 consul常见问题

  1. 节点的服务注销

当服务或节点失效,consul不会对注册的信息进行剔除处理,仅仅标记状态(并且不可使用)。如果担心失效节点和失效服务过多影响监控。可以通过调用HTTP API的形式进行处理:

节点和服务的注销可以使用HTTP API:

  • 注销任意节点和服务:/catalog/deregister
  • 注销当前节点和服务:/agent/service/deregister/:service_id

如果某个节点不继续使用了,也可以在本机使用consul leave命令,或者在其他节点使用consul force-leave 节点id.

  1. 健康检查和故障转移
    在集群环境下,健康检查是由服务注册到Agent来处理的,那么如果这个Agent挂掉了,那么此节点的健康检查就处于无人管理的状态.
    从实际应用看,节点上的服务可能既要被发现,又要发现别的服务,如果节点挂掉了,仅提供被发现了的功能实际上服务还是不可用的.当然发现别的服务也可以不使用本机节点,可以通过访问一个Nginx实现的若干consul节点的负载均衡来实现.