Spring Cloud Eureka+Ribbon+Hystrix

把这三个那来一起讲,是因为这是Spring cloud中最基础的架构,后续的高级配件都是围绕它们来做出优化和升级。

 

Eureka:注册中心,单个微服务将自己注册到eureka上供其它服务调用。

Ribbon:客户端负载均衡,负责对eureka中的服务进行调用。

Hystrix:客户端容错保护,负责当ribbon出现问题时保证整个服务的畅通。

 

基于代码来学习下,创建3个服务:

服务A作为服务中心:https://github.com/yejingtao/forblog/tree/master/demo-eureka-register

服务B作为服务注册到服务A中:https://github.com/yejingtao/forblog/tree/master/demo-eureka-server

服务C调用服务B:https://github.com/yejingtao/forblog/tree/master/demo-eureka-consumer

 

服务A Eureka中心:

Pom依赖

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

(注意cloudDalston版本对应boot1.5版本)

配置文件有3个,其中pee1+peer2是高可用性集群,application.properties是单结点注册中心。

application-peer1.properties

server.port:1111
spring.application.name:eureka-register
eureka.instance.hostname:peer1
eureka.client.serviceUrl.defaultZone:http://peer2:1112/eureka/

application-peer2.properties

server.port:1112
spring.application.name:eureka-register
eureka.instance.hostname:peer2
eureka.client.serviceUrl.defaultZone:http://peer1:1111/eureka/

application.properties

server.port:1111
spring.application.name:eureka-register
eureka.instance.hostname:peer1
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone:http://peer1:1111/eureka/

配置的区别终于在与2个:

eureka.client.registerWithEureka //要不要把自己作为服务注册到eureka

eureka.client.fetchRegistry //要不要去检索服务

这两个默认都是true,多个eureka可以互相注册互相检索组成一个高可用性的集群,如果要搭建单结点注册中心这俩需要配置成false

eureka.client.serviceUrl.defaultZone//注册中心地址,留给微服务结点配置的地址。

这里peer1peer2因为要做集群所以要互相注册,配置对方的地址。

服务组测不需要任何逻辑,所以代码很简单只是启动一个SpringBoot的服务,增加一个@EnableEurekaServer注解启动eureka

为了架构的高可用性我这里决定使用peer1+peer2双结点,eureka启动命令是:

java –jar demo-eureka-register.jar –spring.profiles.active=peer1

java –jar demo-eureka-register.jar –spring.profiles.active=peer2

 

服务B:代码很简单,只是提供一个RestFul服务。

Pom依赖

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

application.yml

server:
  port: 8081
spring:
  application:
    name: hello-service   
eureka:
  client:
    serviceUrl:
      defaultZone: http://peer1:1111/eureka/,http://peer2:1112/eureka/

配置主要有2个,自己注册到eureka上的服务名;Eureka server的地址,多个地址以逗号隔开.

服务代码

@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceDemoApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(ServiceDemoApplication.class, args);
	}	
	
	@Value("${server.port}")
    String port;
	
	
    @RequestMapping("/hi")
    public String home(@RequestParam String name) {
        return "hi "+name+",i am from port:" +port;
    }
}

@EnableEurekaClient代表自己是注册中心的客户端

 

服务CRibbon+Hystrix作为客户端访问注册中心上的服务B

Pom依赖

<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.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
依赖了eureka、ribbon和hystrix。

配置没有特殊的,最主要的就是eureka的地址。

主程序:

//@SpringBootApplication
//@EnableEurekaClient
//@EnableCircuitBreaker
@SpringCloudApplication
public class ConsumerApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(ConsumerApplication.class,args);
	}
	
	@Bean
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}
}

这里只用了@SpringCloudApplication一个注解,因为它包含了其它3个,从名字也可以看得出这是Spring cloud代码的标配。其中@EnableCircuitBreaker是Hystrix的服务熔断。

restTemplate是访问eureka上应用的客户端,因为我的eureka服务端是peer1+peer2双结点的,所以用了@LoadBalanced负责均衡(这里的是客户端负载均衡,与F5、Apache等服务端负载均衡原理差异性很大)。

@Service
public class HelloService {
	
	@Autowired
	private RestTemplate restTemplate;
	
	@HystrixCommand(fallbackMethod="hellServiceFallback")
	public String sayHello() {
		return restTemplate.getForEntity("http://HELLO-SERVICE/hi?name=yejingtao", String.class).getBody();
	}
	
	@SuppressWarnings("unused")
	private String hellServiceFallback() {
		return "error";
	}

}

 restTemplate.getForEntity("http://HELLO-SERVICE/hi?name=yejingtao", String.class).getBody()//用get的方式访问eureka上hello-service上的服务,返回类型是String。

@HystrixCommand(fallbackMethod="hellServiceFallback")//hystrix熔断后服务降级为hellServiceFallback来提供服务。


下面介绍下这几个服务的需要加强学习的知识点。

Eureka:

eureka.instance.lease-renewal-interval-in-seconds=30

eureka.instance.lease-expiratioin-duration-in-seconds=90

失效剔除:超过90eureka没有收到客户端上来的心跳就认为此服务挂了,从注册中心剔除出去(心跳是主动上报的,而不是eureka去访问客户端的/health

自我保护:如果一段时间内eureka管理的85%的服务都失去了心跳,eureka会启动保护机制,它会认为是eureka服务自己所在的网络出现了问题,而不去启用失效剔除机制,继续让注册上来的应用提供服务。


Ribbon的几个特性:

1, 区域亲和策略。可以将同一机房的微服务结点配置成同一个zoneribbon在对服务进行请求时优先选择跟自己同一个zone的结点。eureka.instance.metadataMap.zone=zoneName

2, 重试机制

默认关闭的,需要配置手动打开:spring.cloud.loadbalance.retry.enabled=true

        service-name.ribbon.ConnectTimeOut:请求连接超时时间

        service-name.ribbon.ReadTimeout:请求处理超时时间

        service-name.ribbon.MaxAutoRetries:对当前实例的重试次数

        service-name.ribbon.MaxAutoRetriesNextServer:切换实例的重试次数

        因为微服务中对同一个服务的提供是多结点负载均衡的,如果配置了重试机制,ribbon会先对本次要请求的结点尝试MaxAutoRetriesNextServer次重试,如果还不行就会尝试MaxAutoRetriesNextServer次切换到同一服务的其它结点来提供服务。


Hystrix熔断器:当某个服务单元发生故障之后向调用方返回一个错误而不是一直等待,避免了故障在分布式系统中的蔓延,防止因为一个或几个服务节点的故障导致整个框架的崩盘。

服务降级:fallbackHystrix执行失败的后备服务,fallback也可以发起另一个Hystrix请求。
服务熔断:只有当超过断容器请求数而且失败次数大约一定概率时,才会启动熔断机制。默认是请求20次以上失败50%就启动断熔。

请求缓存:客户端缓存,减少对服务端的http交互次数。@CacheResult@CacheRemove

请求合并:也是为了减少http通信上的消费,但是requestresponse合并和分解也有很大的性能开销,所以要根据场景慎用。

依赖隔离:线程池方式和信号量方式。


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值