在微服务架构中, 业务都会被拆分成一个独立的服务, 服务与服务的通讯是基于 http restful 的. Spring cloud 有两种服务调用方式, 一种是 ribbon+restTemplate, 另一种是 feign. 在这一篇文章首先讲解下基于 ribbon+REST.
一, 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
二, 建一个服务消费者
新建一个 spring-boot 工程, 取名为: service-ribbon; 在它的 pom.xml 继承了父 pom 文件, 并引入了以下依赖:
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.forezp</groupId>
- <artifactId>service-ribbon</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>service-ribbon</name>
- <description>Demo project for Spring Boot</description>
- <parent>
- <groupId>com.forezp</groupId>
- <artifactId>sc-f-chapter2</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
- </dependency>
- </dependencies>
- </project>
在工程的配置文件指定服务的注册中心地址为 http://localhost:8761/eureka/ , 程序名称为 service-ribbon, 程序端口为 8764. 配置文件 application.YAML 如下:
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/
- server:
- port: 8764
- spring:
- application:
- name: service-ribbon
在工程的启动类中, 通过 @EnableDiscoveryClient 向服务中心注册; 并且向程序的 IoC 注入一个 bean: restTemplate; 并通过 @LoadBalanced 注解表明这个 restRemplate 开启负载均衡的功能.
- @SpringBootApplication
- @EnableEurekaClient
- @EnableDiscoveryClient
- public class ServiceRibbonApplication {
- public static void main(String[] args) {
- SpringApplication.run( ServiceRibbonApplication.class, args );
- }
- @Bean
- @LoadBalanced
- RestTemplate restTemplate() {
- return new RestTemplate();
- }
- }
写一个测试类 HelloService, 通过之前注入 IoC 容器的 restTemplate 来消费 service-hi 服务的 "/hi" 接口, 在这里我们直接用的程序名替代了具体的 url 地址, 在 ribbon 中它会根据服务名来选择具体的服务实例, 根据服务实例在请求的时候会用具体的 url 替换掉服务名, 代码如下:
- @Service
- public class HelloService {
- @Autowired
- RestTemplate restTemplate;
- public String hiService(String name) {
- return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
- }
- }
写一个 controller, 在 controller 中用调用 HelloService 的方法, 代码如下:
- @RestController
- public class HelloControler {
- @Autowired
- HelloService helloService;
- @GetMapping(value = "/hi")
- public String hi(@RequestParam String name) {
- return helloService.hiService( name );
- }
- }
在浏览器上多次访问 http://localhost:8764/hi?name=forezp , 浏览器交替显示:
- // 社交电商平台源码请加企鹅求求: 一零三八七七四六二六.
- hi forezp,i am from port:8762
- hi forezp,i am from port:8763
这说明当我们通过调用 restTemplate.getForObject("http://SERVICE-HI/hi?name= http://service-hi/hi?name="+name,String.class) 方法时, 已经做了负载均衡, 访问了不同的端口的服务实例.
来源: https://www.2cto.com/kf/201905/808183.html