在微服务架构中, 服务与服务的通讯是基于 http restful 的 Spring cloud 有两种服务调用方式, 一种是 ribbon+restTemplate, 另一种是 feign 在这一篇文章首先讲解下基于 ribbon
1:ribbon 简介
ribbon 是一个负载均衡客户端, 可以很好的控制 htt 和 tcp 的一些行为 Feign 默认集成了 ribbon
ribbon 已经默认实现了这些配置 bean:
- IClientConfig ribbonClientConfig: DefaultClientConfigImpl
- IRule ribbonRule: ZoneAvoidanceRule
- IPing ribbonPing: NoOpPing
- ServerList ribbonServerList: ConfigurationBasedServerList
- ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter
- ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer
2: 准备工作
首先启动, 上一篇文章中新建的两个工程, 然后将 client 工程复制一个, 命名为 client2, 修改一下配置文件中的端口号, 其他不做修改, 然后启动, 我们会在 eureka 中发现名称为 service-hi 的服务注册了两个这就相当于一个小的集群
3: 建立服务消费者, 如下, 使用 idea 可以直接创建工程, 取名为 service-ribbon;
pom.xm 文件如下:
- <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.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-commons</artifactId>
- <version>RELEASE</version>
- </dependency>
配置文件修改如下:
- eureka.client.service-url.defaultZone=http://localhost:7080/eureka/
- server.port=8084
- spring.application.name= service-ribbon
修改启动类如下:
- /**
- * 通过 @EnableDiscoveryClient 向服务中心注册
- * @author wang_
- */
- @SpringBootApplication
- @EnableDiscoveryClient
- public class ServiceRibbonApplication {
- public static void main(String[] args) {
- SpringApplication.run(ServiceRibbonApplication.class, args);
- }
- /**
- * LoadBalanced 注解表明这个 restRemplate 开启负载均衡的功能
- * return
- */
- @Bean
- @LoadBalanced
- RestTemplate restTemplate() {
- return new RestTemplate();
- }
- }
写一个测试类 HelloService, 通过之前注入 ioc 容器的 restTemplate 来消费 service-hi 服务的 / hi 接口, 在这里我们直接用的程序名替代了具体的 url 地址, 在 ribbon 中它会根据服务名来选择具体的服务实例, 根据服务实例在请求的时候会用具体的 url 替换掉服务名, 代码如下:
- @Service
- public class HelloService {
- @Autowired
- RestTemplate restTemplate;
- @HystrixCommand(fallbackMethod = "hiError")
- public String hiService(String name) {
- return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
- }
- public String hiError(String name) {
- return "hi,"+name+",sorry,error!";
- }
- }
写一个 controller, 在 controller 中用调用 HelloService 的方法, 代码如下:
- @RestController
- public class HelloControler {
- @Autowired
- HelloService helloService;
- @RequestMapping(value = "/hi")
- public String hi(@RequestParam String name) {
- return helloService.hiService(name);
- }
- }
浏览器请求 http://127.0.0.1:8084/hi?name=王
返回结果为下面结果轮换出现,
hi 王, i am from port:8082
hi 王, i am from port:8083
这说明当我们通过调用 restTemplate.getForObject(http://SERVICE-HI/hi?name=+name,String.class) 方法时, 已经做了负载均衡, 访问了不同的端口的服务实例
四此时的架构
一个服务注册中心, eureka server, 端口为 7080
service-hi 工程跑了两个实例, 端口分别为 8082,8083, 分别向服务注册中心注册
sercvice-ribbon 端口为 8084, 向服务注册中心注册
当 sercvice-ribbon 通过 restTemplate 调用 service-hi 的 hi 接口时, 因为用 ribbon 进行了负载均衡, 会轮流的调用 service-hi:8082 和 8083 两个端口的 hi 接口;
来源: http://blog.csdn.net/wang_shuyu/article/details/78685520?from=singlemessage