springcloud(一) eureka集群,负载均衡,轮询

      springcloud:其实说白了就是一个springboot的增强版,但是自己在做的时候发现还是不好做啊,一定要导入springcloud和springboot的pom文件时两种相关的jar包版本要一致。这不自己把eureka集群和负载均衡做个记录以备回顾。

eureka介绍

eureka中的核心概念

Spring Cloud中负载均衡器概览

Spring Cloud中的负载均衡策略

其实eureka里面包含客户端和服务端,关系图如下
springcloud(一) eureka集群,负载均衡,轮询_第1张图片
springcloud(一) eureka集群,负载均衡,轮询_第2张图片
      代码自己放在自己的gitee上了,同时我也把代码粘上来了(其实我觉得初级选手还是先敲,把结果展示出来再研究原理)

(一)代码如下然后开启时是先开启多个eureka在开启生产者最后开启利用feign调用的消费者:

eureka:

   EurekaApplication

package com.springcloud.eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaServer //声明注册中心
public class EurekaApplication {

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

}

   eureka1 properties:

spring.application.name=eurekaserver
server.port=8000
#开启自己当做服务注册
eureka.client.register-with-eureka=true
#开启注册信息
eureka.client.fetch-registry=true
eureka.instance.hostname=eurekaproperties
#eureka.client.registry-fetch-interval-seconds=10
#eureka1 eurekaproperties eureka2 在C:\Windows\System32\drivers\etc\hosts 中 例如加入127.0.0.1 eurekaproperties
eureka.client.serviceUrl.defaultZone=http://eureka1:8001/eureka/,http://eureka2:8002/eureka/
# Running the evict task with compensationTime 0ms
logging.level.com.netflix=warn
#设置为false 关闭自我保护模式,默认是true 。设置为false,否则一个节点挂掉之后,不会在unavailable-replicas中出现
eureka.server.enable-self-preservation=false
#扫描并清理失效服务的间隔时间(单位毫秒,默认是60*1000)即60秒
eureka.server.eviction-interval-timer-in-ms=60000
#定义服务失效的时间,单位:秒 默认值为90  一下就出现在unavailable-replicas !!!lease-expiration-duration-in-seconds 至少应该大于lease-renewal-interval-in-seconds
eureka.instance.lease-expiration-duration-in-seconds=40
#定义服务续约任务(心跳)的调用间隔,单位:秒 默认值为30
eureka.instance.lease-renewal-interval-in-seconds=30
#只有开启自我保护才有用
#eureka.server.renewalPercentThreshold=0.49

注意1:eurekaproperties eureka1 eureka2 在C:\Windows\System32\drivers\etc\hosts中设置。

2:如果是一个eureka(单机)则
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

3:如果开启了security验证则

spring.security.user.password=user
spring.security.user.name=user

那么security 开头的配置是因为引入了spring security保护server端,因此 需要注意 service-url 中的 defaultZone 的值的写法 :
http://用户名:密码@主机:端口/eureka/
如果想关掉security则把下面注解放到启动类上:

@EnableAutoConfiguration(exclude = {
        SecurityAutoConfiguration.class
})

4:关闭不停的节点日志打印:

logging.level.com.netflix=warn

5:Spring Cloud Eureka 自我保护机制(实际上在生产环境或其他环境应该开启)
eureka.server.enable-self-preservation=true 开启 (false 关闭)
#只有开启自我保护才有用(两者是共存的要有都有要无都无)
eureka.server.renewalPercentThreshold=0.49
这个小数到底是多少请参考:
https://www.cnblogs.com/xishuai/p/spring-cloud-eureka-safe.html

6:spring.application.name 表示注册到eureka服务上的名字,建议小写

7:开启自定义健康检查展示健康信息(我在两个生产者上加的自定义健康检查)

配置文件加上

#开启健康检查
eureka.client.healthcheck.enabled=true
#健康信息完整显示  http://localhost:9006/actuator/health  {"status":"DOWN"}  这显示信息少
eureka.management.security.enabled = false
management.endpoint.health.show-details=always

pom:


  org.springframework.boot
   spring-boot-starter-actuator

自定义MyHealthHealthCheckHandler

import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.appinfo.InstanceInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Status;
import org.springframework.stereotype.Component;

@Component
public class MyHealthHealthCheckHandler implements HealthCheckHandler{

    @Autowired
    private MyHealthIndicator myHealthIndicator;

    @Override
    public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus currentStatus){
        Status status=myHealthIndicator.health().getStatus();
        if(status==Status.UP){
            return InstanceInfo.InstanceStatus.UP;
        }else{
            return InstanceInfo.InstanceStatus.DOWN;
        }
    }
}

自定义MyHealthIndicator

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.stereotype.Component;

@Component
public class MyHealthIndicator implements HealthIndicator{

    private int healthIndicatorErrorCount;

    private int healthIndicatorCount;

    private boolean hasError=false;

    @Override
    public Health health(){
        if(!hasError){
            healthIndicatorCount++;
           //每检测5次,就返回DOWN
            if(healthIndicatorCount%5==0){
                hasError=true;
            }
        }else{
            //DOWN计数10次就UP
            healthIndicatorErrorCount++;
            if(healthIndicatorErrorCount>10){
                hasError=false;
                healthIndicatorErrorCount=0;
            }
        }

        if(hasError){
            return new Health.Builder(Status.DOWN).build();
        }
        return new Health.Builder(Status.UP).build();
    }
}

如图访问:http://localhost:9006/actuator/health (9006为down掉的项目的端口)即可显示Down
springcloud(一) eureka集群,负载均衡,轮询_第3张图片
不自定义的话总是显示UP 。自定义后一旦服务所有提供者Down后则http://localhost:8000/actuator/health 永远显示上图,但是消费者调用时就请求不到了。

   eureka2 properties:

spring.application.name=eurekaserver
server.port=8001
#开启自己当做服务注册
eureka.client.register-with-eureka=true
#开启注册信息
eureka.client.fetch-registry=true
eureka.instance.hostname=eureka1
#Eureka自我保护机制
#eureka.server.enable-self-preservation=true
#eureka.client.registry-fetch-interval-seconds=10
eureka.client.serviceUrl.defaultZone=http://eureka2:8002/eureka/,http://eurekaproperties:8000/eureka/
logging.level.com.netflix=warn
#设置为false 关闭自我保护模式,否则一个节点挂掉之后,不会在unavailable-replicas中出现
eureka.server.enable-self-preservation=false
eureka.instance.lease-expiration-duration-in-seconds=10
eureka.instance.lease-renewal-interval-in-seconds=30
eureka.server.eviction-interval-timer-in-ms=1000
#eureka.server.renewalPercentThreshold=0.49

   eureka3 properties:

spring.application.name=eurekaserver
server.port=8002
#开启自己当做服务注册
eureka.client.register-with-eureka=true
#开启注册信息
eureka.client.fetch-registry=true
eureka.instance.hostname=eureka2
#Eureka自我保护机制
#eureka.server.enable-self-preservation=true
#eureka.client.registry-fetch-interval-seconds=10
eureka.client.serviceUrl.defaultZone=http://eurekaproperties:8000/eureka/,http://eureka1:8001/eureka/
logging.level.com.netflix=warn
#设置为false 关闭自我保护模式,否则一个节点挂掉之后,不会在unavailable-replicas中出现
eureka.server.enable-self-preservation=false
eureka.instance.lease-expiration-duration-in-seconds=10
eureka.instance.lease-renewal-interval-in-seconds=30
eureka.server.eviction-interval-timer-in-ms=1000
#eureka.server.renewalPercentThreshold=0.49

   eureka pom:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.0.RELEASE
        
    
    com.springcloud
    eureka
    0.0.1-SNAPSHOT
    eureka
    Demo project for Spring Boot


    
        UTF-8
        UTF-8
        1.8
    
    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
            2.0.0.RELEASE
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
            2.0.0.RELEASE
        

        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix-dashboard
        
        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter-config
        
    
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Finchley.BUILD-SNAPSHOT
                pom
                import
            
        
    
    
        
            spring-snapshots
            Spring Snapshots
            https://repo.spring.io/libs-snapshot
            
                true
            
        
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

production:

    注意:如果是做负载均衡只需在复制粘贴生产者随后改了端口号,其他不需要改动即可!!!!

   HelloController

@RestController
@RequestMapping(value = "/home",method = RequestMethod.GET)
public class HelloController {

    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String index(@RequestParam String name) {
        return "hello "+name+",this is first messge";
    }
}

   ProductionApplication

package com.springcloud.production;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
//禁用Security 避免输入账号密码
@EnableAutoConfiguration(exclude = {
        SecurityAutoConfiguration.class
})
@EnableDiscoveryClient
public class ProductionApplication {

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

}

注意:@EnableDiscoveryClient 启用服务注册与发现(表示这是客户端)
Eureka 使用 @EnableEurekaClient或者@EnableDiscoveryClient,其他的服务发现代理使用@EnableDiscoveryClient

   application.properties

spring.application.name=production
server.port=9006
eureka.client.serviceUrl.defaultZone=http://eurekaproperties:8000/eureka/

   Production pom



    4.0.0
    com.springcloud
    production
    0.0.1-SNAPSHOT
    production
    jar
    Demo project for Spring Boot
    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.0.RELEASE
        
    
    
        UTF-8
        UTF-8
        1.8
    
    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
            2.0.0.RELEASE
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
            2.0.0.RELEASE
        
        
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix-dashboard
        
        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter-config
        
    
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Finchley.BUILD-SNAPSHOT
                pom
                import
            
        
    
    
        
            spring-snapshots
            Spring Snapshots
            https://repo.spring.io/libs-snapshot
            
                true
            
        
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

consumer:

   ConsumerController:

package com.springcloud.consumer.controller;

import com.springcloud.consumer.service.HelloRemoteService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class ConsumerController {

    @Autowired
    private HelloRemoteService helloRemoteService;
	
    @RequestMapping(value = "/hello/{name}",method = RequestMethod.GET)
    public String index(@PathVariable("name") String name) {
        return helloRemoteService.hello(name);
    }

}

HelloRemoteService:

package com.springcloud.consumer.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Created by summer on 2017/5/11.
 */
//path 对应controller中的
@FeignClient(name = "production", path = "/home")
public interface HelloRemoteService {

    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello(@RequestParam("name") String name);


}

   ConsumerApplication:

package com.springcloud.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
//禁用Security 避免输入账号密码
@EnableAutoConfiguration(exclude = {
        SecurityAutoConfiguration.class
})
@EnableDiscoveryClient //启用服务注册与发现
@EnableFeignClients  //启用feign进行远程调用
public class ConsumerApplication {

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

}

   consumer properties:

spring.application.name=consumer
server.port=9001
eureka.client.serviceUrl.defaultZone=http://eurekaproperties:8000/eureka/

   comsumer pom:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.0.RELEASE
        
    
    com.springcloud
    consumer
    0.0.1-SNAPSHOT
    consumer
   
    Demo project for Spring Boot

    
        UTF-8
        UTF-8
        1.8
    
    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
            2.0.0.RELEASE
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
            2.0.0.RELEASE
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix-dashboard
        
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        
        
        
            io.springfox
            springfox-swagger2
            2.9.2
        
        
            io.springfox
            springfox-swagger-ui
            2.9.2
        
        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.security
            spring-security-config
            4.1.0.RELEASE
        
        
            org.springframework.security
            spring-security-web
            4.1.0.RELEASE
        
    
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Finchley.BUILD-SNAPSHOT
                pom
                import
            
        
    
    
        
            spring-snapshots
            Spring Snapshots
            https://repo.spring.io/libs-snapshot
            
                true
            
        
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

(二)报错整理:

   (1)当你在启动三个eureka的时候会发现有的eureka报错

com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect

   对于这个错,是在第一个节点eureka-server1启动后,向eureka-server2注册时连接拒绝(java.net.ConnectException: Connection refused: connect)导致,因为此时eureka-server2节点还未启动,所有出现此类错误信息是正常的,eureka-server2启动后,此类错误日志将不会出现。关于各类集群环境不同节点在顺次启动时都会出现类似错误信息的,大家不必惊慌

   先点击pom把所有项目的pom文件导入如下:
springcloud(一) eureka集群,负载均衡,轮询_第4张图片

   启动的时候首先的保证把下图中默认的打钩去掉,意思是可以同时启动(启动一个在启动另一个)多个实例
springcloud(一) eureka集群,负载均衡,轮询_第5张图片

springcloud(一) eureka集群,负载均衡,轮询_第6张图片
eureka2是application-eureka2.properties 中的eureka2springcloud(一) eureka集群,负载均衡,轮询_第7张图片

   (2)所有eureka跑完后发现eureka客户端里面有类似于如下的红字信息,就我知道的应该是配置文件中client 和server中配置不合适导致的,但是不影响功能

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

springcloud(一) eureka集群,负载均衡,轮询_第8张图片
(三)eureka常用配置属性:

   参考:https://segmentfault.com/a/1190000008378268

eureka.client.register-with-eureka=true
   开启自己当做服务注册(单机话设为false,集群则设为true。和下面一个注解是共用的)

eureka.client.fetch-registry=true
   即不去检索服务(单机话设为false,集群则设为true

eureka.client.registry-fetch-interval-seconds
   表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒

eureka.instance.lease-expiration-duration-in-seconds
   leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,告诉服务端,如果我2s之内没有给你发心跳,就代表我“死”了,将我踢出掉。测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务

  • 默认为90秒
  • 如果该值太大,则很可能将流量转发过去的时候,该instance已经不存活了。
  • 如果该值设置太小了,则instance则很可能因为临时的网络抖动而被摘除掉。
  • 该值至少应该大于leaseRenewalIntervalInSeconds

eureka.instance.lease-renewal-interval-in-seconds
   leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance。除此之外,如果该instance实现了HealthCheckCallback,并决定让自己unavailable的话,则该instance也不会接收到流量。

  • 默认30秒

eureka.server.enable-self-preservation
   是否开启自我保护模式,默认为true。

   默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。

   Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

   综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

eureka.server.eviction-interval-timer-in-ms
   eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒。

(四)注解使用:

(1)禁用Security 避免输入账号密码验证

写在启动类那里

@EnableAutoConfiguration(exclude = {
        SecurityAutoConfiguration.class
})

(2)启用服务注册与发现

写在启动类那里

@EnableDiscoveryClient

(3)启用feign进行远程调用

写在启动类那里

@EnableFeignClients 

结合使用@FeignClient(name = “production”, path = “/home”)

name: spring.application.name=production 中的名称
path:被调用者的路径.。总之consumer中路径拼接起来要和生产者一样

@FeignClient(name = "production", path = "/home")
public interface HelloRemoteService {

    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello(@RequestParam("name") String name);
}

(4)声明注册中心Eureka

写在启动类那里

@EnableEurekaServer

(五)集群展示图:

localhost:9091/hello/{name} 输入例如:localhost:9091/hello/ljlo

按enter回车键来回切换
springcloud(一) eureka集群,负载均衡,轮询_第9张图片
springcloud(一) eureka集群,负载均衡,轮询_第10张图片

你可能感兴趣的:(springcloud)