概述
在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于 http restful 的。Spring cloud 有两种服务调用方式,一种是 ribbon + restTemplate ,另一种是 feign 。在这一篇文章首先讲解下基于 ribbon + rest。
Ribbon 简介
Ribbon 是一个负载均衡客户端,可以很好的控制 http
和 tcp
的一些行为。
准备工作
启动服务提供者(本教程案例工程为:hello-spring-cloud-service-admin),端口号为:8762
修改配置文件的端口号为:8763,启动后在 Eureka 中会注册两个实例,这相当于一个小集群
创建服务消费者
创建一个工程名为 hello-spring-cloud-web-admin-ribbon
的服务消费者项目,pom.xml
配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 <?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 > <parent > <groupId > com.example</groupId > <artifactId > hello-spring-cloud-dependencies</artifactId > <version > 1.0.0-SNAPSHOT</version > <relativePath > ../hello-spring-cloud-dependencies/pom.xml</relativePath > </parent > <artifactId > hello-spring-cloud-web-admin-ribbon</artifactId > <packaging > jar</packaging > <name > hello-spring-cloud-web-admin-ribbon</name > <url > http://wvincen.gitee.io</url > <inceptionYear > 2019-Now</inceptionYear > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-tomcat</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-thymeleaf</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-actuator</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-starter-netflix-eureka-server</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-ribbon</artifactId > </dependency > <dependency > <groupId > net.sourceforge.nekohtml</groupId > <artifactId > nekohtml</artifactId > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <configuration > <mainClass > com.example.hello.spring.cloud.web.admin.ribbon.WebAdminRibbonApplication</mainClass > </configuration > </plugin > </plugins > </build > </project >
主要是增加了 Ribbon 的依赖
1 2 3 4 <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-ribbon</artifactId > </dependency >
Application
通过 @EnableDiscoveryClient
注解注册到服务中心
1 2 3 4 5 6 7 8 9 10 11 12 13 package com.funtl.hello.spring.cloud.web.admin.ribbon;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication @EnableDiscoveryClient public class WebAdminRibbonApplication { public static void main (String[] args) { SpringApplication.run(WebAdminRibbonApplication.class, args); } }
application.yml
设置程序端口号为:8764
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 spring: application: name: hello-spring-cloud-web-admin-ribbon thymeleaf: cache: false mode: LEGACYHTML5 encoding: UTF-8 servlet: content-type: text/html server: port: 8764 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/
Configuration
配置注入 RestTemplate
的 Bean,并通过 @LoadBalanced
注解表明开启负载均衡功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.funtl.hello.spring.cloud.web.admin.ribbon.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;@Configuration public class RestTemplateConfiguration { @Bean @LoadBalanced public RestTemplate restTemplate () { return new RestTemplate(); } }
创建测试用的 Service
在这里我们直接用的程序名替代了具体的 URL 地址,在 Ribbon 中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的 URL 替换掉服务名,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.funtl.hello.spring.cloud.web.admin.ribbon.service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;@Service public class AdminService { @Autowired private RestTemplate restTemplate; public String sayHi (String message) { return restTemplate.getForObject("http://HELLO-SPRING-CLOUD-SERVICE-ADMIN/hi?message=" + message, String.class); } }
创建测试用的 Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.funtl.hello.spring.cloud.web.admin.ribbon.controller;import com.funtl.hello.spring.cloud.web.admin.ribbon.service.AdminService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@RestController public class AdminController { @Autowired private AdminService adminService; @RequestMapping(value = "hi", method = RequestMethod.GET) public String sayHi (@RequestParam String message) { return adminService.sayHi(message); } }
测试访问
在浏览器上多次访问:http://localhost:8764/hi?message=HelloRibbon ,浏览器交替显示:
1 2 Hi,your message is :"HelloRibbon" i am from port:8762 Hi,your message is :"HelloRibbon" i am from port:8763
请求成功则表示我们已经成功实现了负载均衡功能来访问不同端口的实例
此时的架构
一个服务注册中心,Eureka Server,端口号为:8761
service-admin
工程运行了两个实例,端口号分别为:8762
,8763
web-admin-ribbon
工程端口号为:8764
web-admin-ribbon
通过 RestTemplate
调用 service-admin
接口时因为启用了负载均衡功能故会轮流调用它的 8762
和 8763
端口
附
在 IDEA 中配置一个工程启动多个实例
步骤一
点击 Run -> Edit Configurations...
步骤二
选择需要启动多实例的项目并勾上 Allow parallel run
前面的勾
步骤三
通过修改 application.yml
配置文件的 server.port
的端口,启动多个实例,需要多个端口,分别进行启动即可。
案例源码:https://github.com/V-Vincen/hello-spring-cloud
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !