eureka最后一章我们讲了使用RestTemplet
在java内调用接口,Ribbon是一个可以用来做负载均衡(主要)和远程调用
的一个东西,远程调用的话大概有两类:
- 结合
RestTemplet
类使用 - 结合
openFeign
使用
1、结合RestTemplet
使用
1.1、搭建项目配置eureka
新建一个Ribbon项目,路径如下,使用阿里云搭建项目
搜索依赖并导入,然后点击finish创建成功
创建成功后,我们修改springboot版本和springcloud版本
然后我们修改配置文件,注册到eureka里
server: port: 9980 spring: application: name: ribbonStudy eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: hostname: localhost instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} prefer-ip-address: true # 显示ip
修改好后,我们去启动类添加注解
EnableEurekaClient
,到此eureka配置完毕
1.2、搭建两个集群服务,编写一样的接口注册到eureka里
搭建eureka集群步骤,在 eureka入门文章 里写过了,就省略了(记得修改依赖版本)
这里因为要使用负载均衡,所以只修改了返回值内容用来检测负载均衡是否启用
项目a的controller
package com.tcc.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author 宇辰 * @date 2022/8/7 - 21:02 **/ @RestController public class TestController { @GetMapping("testGet") public String testGet(){ return "我是a大"; } }
项目aa的controller
package com.tcc.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author 宇辰 * @date 2022/8/7 - 21:02 **/ @RestController public class TestController { @GetMapping("testGet") public String testGet(){ return "我是a2"; } }
搭建好提供者后,我们在
Ribbon
项目里使用RestTemplet
来远程调用其他服务的接口
为了方便我们使用
RestTemplet
类,我们直接把他注册到bean里,后续使用直接在controller里注入即可使用package com.tcc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableEurekaClient public class RibbonStudyApplication { public static void main(String[] args) { SpringApplication.run(RibbonStudyApplication.class, args); } // 以后使用这个类直接注入即可 @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
我们在Ribbon项目里创建controller
package com.tcc.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; /** * @author 宇辰 * @date 2022/9/25-14:08 **/ @RestController public class TestController { @Autowired private RestTemplate restTemplate; @RequestMapping("testGet") // 传入服务名称 上一章eureka里讲过 public String testGet(String serviceName){ String url = "http://" + serviceName + "/testGet"; String testGet = restTemplate.getForObject(url, String.class); return testGet; } }
到此为止,所有基础搭建完成,下面使用
Ribbon
来完成
1.3、使用Ribbon
做服务远程调用及负载均衡(重要)
使用
Ribbon
很简单,只需要在我们注入的RestTemplet
上添加一个注解即可:@LoadBalanced
添加完成后,我们就可以在页面上访问:
http://localhost:9980/testGet?serviceName=自己搭建的服务的服务名称
路径查看是否调用成功
负载均衡默认采用轮询算法,当我们再次刷新页面可以看到效果
到此,结合RestTemplet
类实现服务调用和负载均衡
效果就实现了
注意:如果想要自定义ip和端口的话,就不能使用自动装配的RestTemplet
了,因为bean容器里的这个类已经被Ribbon托管了
2、结合openFeign
使用
后面讲解openFeign
使用…
3、Ribbon配置
3.1、指定负载均衡(算法)
负载均衡有很多种算法,Ribbon也提供了几种算法,默认为:轮询算法。我们可以自己指定哪个服务使用哪种算法,或者全部服务使用一种算法。
负载均衡算法:
1)随机算法:负载均衡⽅法随机的把负载分配到各个可⽤的服务器上,通过随机数⽣成算法选取⼀个服务器,然后把连接发送给它。虽然许多均衡产品都⽀持该算法,但是它的有效性⼀直受到质疑,除⾮把服务器的可运⾏时间看的很重。
2)轮询算法:轮询算法按顺序把每个新的连接请求分配给下⼀个服务器,最终把所有请求平分给所有的服务器。轮询算法在⼤多数情况下都⼯作的不错,但是如果负载均衡的设备在处理速度、连接速度和内存等⽅⾯不是完全均等,那么效果会更好。
3)加权轮询算法:该算法中,每个机器接受的连接数量是按权重⽐例分配的。这是对普通轮询算法的改进,⽐如你可以设定:第三台机器的处理能⼒是第⼀台机器的两倍,那么负载均衡器会把两倍的连接数量分配给第3台机器。
4)动态轮询算法:类似于加权轮询,但是,权重值基于对各个服务器的持续监控,并且不断更新。这是⼀个动态负载均衡算法,基于服务器的实时性能分析分配连接,⽐如每个节点的当前连接数或者节点的最快响应时间等。
5)最快算法:最快算法基于所有服务器中的最快响应时间分配连接。该算法在服务器跨不同⽹络的环境中特别有⽤。
6)最少连接算法:系统把新连接分配给当前连接数⽬最少的服务器。该算法在各个服务器运算能⼒基本相似的环境中⾮常有效。
7)观察算法:该算法同时利⽤最⼩连接算法和最快算法来实施负载均衡。服务器根据当前的连接数和响应时间得到⼀个分数,分数较⾼代表性能较好,会得到更多的连接。
8)预判算法:该算法使⽤观察算法来计算分数,但是预判算法会分析分数的变化趋势来判断某台服务器的性能正在改善还是降低。具有改善趋势的服务器会得到更多的连接。该算法适⽤于⼤多数环境。
下面我们在项目中演示
1、指定项目使用指定的算法
只需要在application.yml
里添加下面配置
eureka-cli-a: # 指定的服务名称
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 可以查看IRule.java的实现类算法的权限定名
可以配置完自行测试
2、全局使用的算法
只需要在启动类中,添加如下代码即可,也可以自己实现IRule
接口,编写自己的算法
@Bean
public IRule myRule(){
return new RandomRule(); // 返回想要使用的规则类
}
3.2、其他配置
ribbon:
eager-load:
enabled: false # ribbon它只有自己的话,是不能做服务发现的,必须要借助eureka ribbon需要去eureka中获取服务列表,如果false就懒加载
eureka:
enabled: true # 使用eureka
http: # 我们使用ribbon 用的restTemplate发送请求实际上是用的java.net.HttpUrlConnection发送的请求 很方便,但不支持连接池
client: # 发请求的工具有很多 httpClient 它支持连接池 效率更好,如果想修改请求的工具,记得添加这个依赖
enabled: false
okhttp: # 也是个请求的工具,移动端用的比较多 轻量级的请求
enabled: false
4、轮询算法思路
轮询是采用取模的算法
// 首先要有个list集合存放所有服务
List<> service = new List<>();
int num = 1;
// 如果前台访问了,就让访问次数+1
if(前台访问了){
num ++
}
// 数组下标就是让 访问次数 % service.size() 这样就可以保证结果永远不大于集合的size
// 返回 结果调用的服务
return service.get(num % service.size())