一, 负载均衡的简介:
负载均衡是高可用架构的一个关键组件, 主要用来提高性能和可用性, 通过负载均衡将流量分发到多个服务器, 多服务器能够消除单个服务器的故障, 减轻单个服务器的访问压力.
1, 服务端负载均衡: 客户端请求到负载均衡服务器, 负载均衡服务器根据自身的算法将该请求转给某台真正提供业务的服务器, 该服务器将响应数据给负载均衡服务器, 负载均衡服务器最后将数据返回给客服端, 服务端负载均衡完全由服务器处理, 客户端不需要做任何事情. 常见例子, 例如: nginx
2, 客服端负载均衡: 基于客户端的负载均衡, 简单的说就是在客户端程序里面, 维护一组服务器引用, 自己设定一个调度算法, 在向服务器发起请求的时候, 先执行调度算法计算出向哪台服务器发起请求, 然后再发起请求给服务器, 常见例子, 例如: Ribbon
二, Ribbon 的简介:
上一篇文章, 讲了服务的注册和发现. 在微服务架构中, 业务都会被拆分成一个独立的服务, 服务与服务的通讯是基于 http restful 的. Spring cloud 提供两种服务调度方式, 一种方式是 ribbon+restTemplate, 另一种方式是 feign. 这章先讲解下基于 ribbon+restful 的服务请求方式.
ribbon 是一个负载均衡客户端, 提供了很多在 HTTP 和 TCP 客户端之上的控制. Feign 内部也已经使用了 Ribbon, 所以只要使用了 @FeignClient 注解, 也能实现本章功能.
三, 准备集群服务:
通过标题我们也知道 ribbon 有负载均衡的功能, 所以首先需要准备一个服务器集群. 这一篇文章基于上一篇文章的工程, 继续进行完善的.
有些功能的命名及新增 springcloud 模块, 不太清楚的同学, 可以参考: 第二章: 服务注册和发现组件 (Eureka)
1. 启动 eureka-server 工程, eureka 注册中心就启动了.
2. 启动 springcloud-eureka-client 工程, 上篇文章我们知道 springcloud-eureka-client 工程的端口为 9300.
3. 将 springcloud-eureka-client 工程的端口改成 9400(修改 application.properties 文件), 然后再启动 springcloud-eureka-client.
通过上面三个步骤, 我们就相当于在 eureka 服务上启动了两个 springcloud-eureka-client 服务, 但是端口号不同, 输入 http://localhost:8761/ 查看页面效果
四, 新建 Ribbon 客户端模块:
重新新建一个 spring-boot 工程, 取名为: springcloud-ribbon-client
1. 修改 pom.xml 文件 (parent 标签的内容引入的是第二章创建的父 pom, 后续新建的模块都会引用. 然后在父 pom 的 < modules > 标签中加入 <module>springcloud-ribbon-client</module > 配置, 将新建的模块依赖到父模块.
ps: 有些同学没有按照顺序来, 自己在 parent 标签中, 直接引入 springboot 的父 pom, 其实也可以, 但是如果报错一定要注意, springboot 的版本与 springcloud 的版本是否匹配.
我们父 pom 中 springboot 的版本号为: <version>2.1.4.RELEASE</version>,springcloud 的版本号为: <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
直接看本章, 有不清楚的同学可以参考: 一起来学 Spring Cloud | 第二章: 服务注册和发现组件 (Eureka)
- <?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.haly</groupId>
- <artifactId>springcloud</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
- <groupId>com.haly</groupId>
- <artifactId>springcloud-ribbon-client</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>springcloud-ribbon-client</name>
- <description > 新建一个 springcloud 项目 </description>
- <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>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>
2. 修改 springcloud-ribbon-client 的配置文件 application.properties
- server.port=9500
- spring.application.name=springcloud-ribbon-client
- eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
3. 在工程的启动类中, 新增注解配置
@EnableDiscoveryClient 向服务中心注册, 并且注册了一个叫 restTemplate 的 bean.
@ LoadBalanced 注解表明, 这个 restRemplate 是需要做负载均衡的.
- package com.haly.springcloud;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
- import org.springframework.cloud.client.loadbalancer.LoadBalanced;
- import org.springframework.context.annotation.Bean;
- import org.springframework.Web.client.RestTemplate;
- @SpringBootApplication
- @EnableDiscoveryClient
- public class SpringcloudRibbonClientApplication {
- public static void main(String[] args) {
- SpringApplication.run(SpringcloudRibbonClientApplication.class, args);
- }
- @Bean
- @LoadBalanced
- RestTemplate restTemplate() {
- return new RestTemplate();
- }
- }
4. 新建一个 service 类, 用来调用第二章在 springcloud-eureka-client 模块中的 hello 方法, 详情参考: 一起来学 Spring Cloud | 第二章: 服务注册和发现组件 (Eureka)
- package com.haly.springcloud.service;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.Web.client.RestTemplate;
- @Service
- public class RibbonService {
- @Autowired
- RestTemplate restTemplate;
- public String getHello(String name) {
- return restTemplate.getForObject("http://springcloud-eureka-client/hello?name="+name,String.class);
- }
- }
ps: 我们请求时用 springcloud-eureka-client 服务名代替了 ip 地址, 在 ribbon 中它会根据服务名来选择具体的服务实例, 根据服务实例在请求的时候会用具体的 url 替换掉服务名.
5. 新建一个 controller 名为: RibbonController, 来接收浏览器访问, RibbonController 的 getHello 方法调用 RibbonService 的 getHello 方法
- package com.haly.springcloud.controller;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.Web.bind.annotation.GetMapping;
- import org.springframework.Web.bind.annotation.RequestParam;
- import org.springframework.Web.bind.annotation.RestController;
- import com.haly.springcloud.service.RibbonService;
- @RestController
- public class RibbonController {
- @Autowired
- RibbonService ribbonService;
- @GetMapping(value = "/getHello")
- public String getHello(@RequestParam String name) {
- return ribbonService.getHello(name);
- }
- }
6. 打开浏览器输入 http://localhost:9500/getHello?name=young 码农 多次访问页面会交替出现如下结果
从上图可以验证, 当我们通过调用 restTemplate.getForObject("http://springcloud-eureka-client/hello?name="+name,String.class) 方法时, 已经做了负载均衡, 访问了不同的端口的服务实例.
五, 实验总结:
项目结构:
1. 一个服务注册中心, eureka server, 端口为 8761
2. springcloud-eureka-client 工程跑了两个实例, 端口分别为 9300,9400, 分别向服务注册中心注册
3. springcloud-ribbon-client 端口为 9500, 向服务注册中心注册
4. 当 springcloud-ribbon-client 通过 restTemplate 调用 springcloud-eureka-client 的 hello 接口时, 因为用 ribbon 进行了负载均衡, 会轮流的 9300 和 9400 两个服务端口的 hello 接口
来源: https://www.cnblogs.com/haly/p/10840119.html