本文基于前两篇文章eureka-server和eureka-client的实现。 参考
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> 复制代码
application.yml
spring: application: name: eureka-ribbon server: port: 8901 eureka: instance: hostname: localhost lease-renewal-interval-in-seconds: 5 lease-expiration-duration-in-seconds: 10 client: service-url: defaultZone: http://eureka1.server.com:8701/eureka/,http://eureka2.server.com:8702/eureka/,http://eureka3.server.com:8703/eureka/ 复制代码
package spring.cloud.demo.eurekaribbon; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.hystrix.EnableHystrix; @EnableDiscoveryClient @SpringBootApplication public class EurekaRibbonApplication { public static void main(String[] args) { SpringApplication.run(EurekaRibbonApplication.class, args); } } 复制代码
@EnableDiscoveryClient启动eureka服务发现相关配置
package spring.cloud.demo.eurekaribbon.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; /** * @auther: maomao * @DateT: 2019-09-17 */ @Configuration public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } } 复制代码
@LoadBalanced 实现负载均衡
package spring.cloud.demo.eurekaribbon.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; /** * @auther: maomao * @DateT: 2019-09-17 */ @Service public class EurekaRibbonService { @Autowired RestTemplate restTemplate; public String sayHello() { String message; try { message = restTemplate.getForObject("http://eureka-client/info", String.class); } catch (RestClientException e) { message = e.getMessage(); } return message; } } 复制代码
http://eureka-client/info , 其中eureka-client为服务提供者对应的spring.application.name
package spring.cloud.demo.eurekaribbon.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import spring.cloud.demo.eurekaribbon.service.EurekaRibbonService; /** * @auther: maomao * @DateT: 2019-09-17 */ @RestController public class EurekaRibbonConntroller { @Autowired private EurekaRibbonService eurekaRibbonService; @RequestMapping("/syaHello") public String syaHello() { String message = eurekaRibbonService.sayHello(); return "ribbon result: " + message; } } 复制代码
前题保证eureka-server和eureka-client已经正常启动。然后启动eureka-ribbon服务。 在浏览器输入http://localhost:8901/syaHello,如下图所示:
多次刷新后可以看到浏览器显示的是结果中端口是变化的。
至此,一个简单的单点Ribbon服务消费者就搭建完成。
场景:假如在生产环境中,访问量很大的情况下,那么就会产生很多请求阻塞的情况,然后服务器的内存消耗就会陡增,严重情况下会导致系统的崩溃,也就是常见的雪崩。为了避免这种情况,熔断保护机制就迎刃而生。在访问不通的情况下,要及时作出响应,而不是等待超时。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> 复制代码
package spring.cloud.demo.eurekaribbon.service; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; /** * @auther: maomao * @DateT: 2019-09-17 */ @Service public class EurekaRibbonService { @Autowired RestTemplate restTemplate; @HystrixCommand( commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000"), @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD")}, fallbackMethod = "syaHelloFailure") public String sayHello() { String message; try { message = restTemplate.getForObject("http://eureka-client/info", String.class); } catch (RestClientException e) { message = e.getMessage(); } return message; } public String syaHelloFailure() { System.out.println("error come in "); String message = "网络繁忙, 请稍后再试"; return message; } } 复制代码
停掉其中一台服务,多次访问http://localhost:8901/syaHello会出现如下图情况,
可以看出,当出现服务访问不通的情况,会返回对应的错误信息。