简介

最近都在弄微服务的东西,现在来记录下收获。我从一知半解到现在能从0搭建使用最大的感触有两点

1.微服务各大组件的版本很多,网上很多博客内容不一定适合你的版本,很多时候苦苦琢磨都是无用功

2.网上博客参差不齐,有些甚至错误的。更离谱的是,好的文章阅读量除非高出天际,不然就都很低,比那些复制粘贴,随便应付的都低(这个搜索推荐算法不知道基于什么的)

通过这段时间学习,我觉得最重要是从好的博客入手,先不要着急怎么组件怎么使用,而是先了解组件的作用,大概的原理,然后才是使用,这样搭建和尝试的过程中才能更好的定位问题,最后再次回到原理和一些实际问题的处理(不知道实际问题怎样的,直接搜那个组件的面试题往往效果最好)

接下来的内容,都以导航的形式展现给大家(毕竟优秀的轮子很多,直接看大佬写的不香嘛),再顺带提些自己的理解

传送门

更多微服务的介绍可点击下方链接

微服务介绍Nginx导航Nacos导航Gateway导航Ribbon导航Feign导航Sentinel导航

博主微服务git练手项目:https://github.com/NiceJason/SpringCloudDemo

Ribbon简介

ribbon简介:https://blog.csdn.net/f641385712/article/details/104761814

说到负载均衡,常指两个地方:Ng负载均衡和服务负载均衡。服务负载均衡指SpringCloudGateWay网关开始,到里面的各种Server服务,都是基于Ribbon进行负载均衡的。

SpringCloud下的Ribbon

参考资料:https://louluan.blog.csdn.net/article/details/83060310

文章讲了Ribbon几大核心组件的作用和负载均衡的过程,当然总的流程是这样的,但是和具体的组件结合时候会有点变化,例如和Nacos结合时,Nacos并没有实现自己的IPing,而是把这个定时检测都去掉了,换成了定时刷新服务列表(自身每10秒刷新),外部Ribbon没变,一样是每30秒刷新一次

在文章开头也讲了Feign和Ribbon结合,所以重试机制默认Feign是关闭的(具体代码里可以看到),调用的是Ribbon。同理可以推测出,和Ribbon整合的组件(如SpringCloudGateaWay)他们的重试机制应该都是基于Ribbon,因此Ribbon的配置十分重要

Ribbon的重试机制

参考资料:https://blog.csdn.net/east123321/article/details/82385816(这篇文章的评论也能看看)

想要Ribbon开启重试,需要导入SpringRetry包,因为Ribbon重试先关的类和拦截器都依赖RetryTemplate.class,代码里写着ConditionOnClass(RetryTemplate.class)。

这个太重要了,不知道为什么很多博客都没提及,没有依赖此包Ribbon并不会报错和提示,所以找了很久没不知道什么问题

   <!--重试依赖-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>

这里的版本应该依赖于Springboot而不是自己去指定

ribbon:
ReadTimeout: 15000
ConnectTimeout: 5000
MaxAutoRetries: 1 #同一台实例最大重试次数,不包括首次调用
MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最大重试次数,不包括首次调用
OkToRetryOnAllOperations: false #是否所有操作都重试,改为true要注意接口是否实现了幂等性
重试次数: MaxAutoRetries + MaxAuthRetriesNextServer * ( 1 + MaxAutoRetries) ,这里面的1是指MaxAutoRetries首次调用
 
总共调用次数为:(1+ MaxAutoRetriesNextServer)*(1 + MaxAutoRetries ),两边的1都是首次调用,拆开了其实就是上面的公式少了1次
 
如果不配置ribbon的重试次数,默认重试1次
注意:
默认情况下,GET方式请求无论是连接异常还是读取异常,都会进行重试
非GET方式请求,只有连接异常时,才会进行重试

Ribbon的配置

############## ribbon配置 ##############
#想要更好的理解Nacos和Ribbon的结合,关闭饥饿加载,打断点
ribbon.eager-load.enabled=true
## 从注册中心刷新servelist的时间 默认30秒,单位ms
ribbon.ServerListRefreshInterval=15000
## 请求连接的超时时间 默认1秒,单位ms。更改这个值时,需要考虑熔断时间是否要重新计算
ribbon.ConnectTimeout=1000
## 请求处理的超时时间 默认1秒,单位ms。更改这个值时,需要考虑熔断时间是否要重新计算
ribbon.ReadTimeout=10000
#同一台实例最大重试次数,不包括首次调用。更改这个值时,需要考虑熔断时间是否要重新计算
ribbon.MaxAutoRetries=2
#重试负载均衡其他的实例最大重试次数,不包括首次调用。更改这个值时,需要考虑熔断时间是否要重新计算
ribbon.MaxAutoRetriesNextServer=2
#是否所有操作都重试 可能存在幂等性问题,在幂等性未解决之前设置为false,只有get请求会进行重试
ribbon.OkToRetryOnAllOperations=false

@LoadBalance的使用

将@LoadBalance注解放在RestTemplate上便能赋予RestTemplate负载均衡的能力

1   @LoadBalanced
2 @Autowired
3 RestTemplate restTemplate;

为什么这么神奇,这其实涉及到Spring注解的使用,详情看:https://fangshixiang.blog.csdn.net/article/details/100890879

@Qualifier+@Autowired可以加载指定类型的类,这样在系统启动的时候就可以获得这部分特殊的类进行加强

我们可以学习这种设计模式,对一些老旧的工具类(自己建的或者第三方的)进行升级而不影响原来的业务逻辑

针对@LoadBalanced下的RestTemplate的使用,我总结如下细节供以参考:
1.传入的String类型的url必须是绝对路径(http://...),否则抛出异常:java.lang.IllegalArgumentException: URI is not absolute
2.serviceId不区分大小写(http://user/...效果同http://USER/...)
3.serviceId后请不要跟port端口号了~
标注有@LoadBalancedRestTemplate只能书写serviceId而不能再写IP地址/域名去发送请求了。若你的项目中两种case都有需要,请定义多个RestTemplate分别应对不同的使用场景~

自定义Rule

 1 /**
2 * @Author DiaoJianBin
3 * @Description Ribbon的自定义规则
4 * 仿照NacosRule进行书写
5 * 如果直接加@Compoment,将会成为user-service里的全局规则
6 * 无论请求哪个服务,都会用此规则,这样不好,所以在配置文件中指定
7 * @Date 2021/3/10 14:51
8 */
9 public class CustomRuleA extends AbstractLoadBalancerRule {
10
11 @Autowired
12 private NacosDiscoveryProperties nacosDiscoveryProperties;
13 @Autowired
14 private NacosServiceManager nacosServiceManager;
15
16 @Override
17 public void initWithNiwsConfig(IClientConfig clientConfig) {
18 System.out.println("CustomRuleA初始化,这里有各种配置信息可以获得,可以debug此处查看clientConfig里面的信息");
19 }
20
21 @SneakyThrows
22 @Override
23 public Server choose(Object key) {
24
25 //获取服务配置的集群名
26 String clusterName = nacosDiscoveryProperties.getClusterName();
27 //当前的版本号 配置文件配置的metadata信息
28 String currentVersion = nacosDiscoveryProperties.getMetadata().get("version");
29 System.out.println("当前服务集群名称="+clusterName+" 版本号="+currentVersion);
30 //获得当前服务分组
31 String group = nacosDiscoveryProperties.getGroup();
32 //获取负载均衡器
33 ZoneAwareLoadBalancer baseLoadBalancer = (ZoneAwareLoadBalancer) getLoadBalancer();
34 //调用服务的名字
35 String invokedServerName = baseLoadBalancer.getName();
36 //获取namingServer(包含nacos注册发现相关api)
37 NamingService namingService = nacosServiceManager.getNamingService(nacosDiscoveryProperties.getNacosProperties());
38 //获取被调用的服务的所有实例
39 List<Instance> invokedAllInstanceList = namingService.getAllInstances(invokedServerName,group);
40
41 Instance instance = null;
42 if(invokedAllInstanceList.size()>0){
43 //默认获取最后一个
44 instance = invokedAllInstanceList.get(invokedAllInstanceList.size()-1);
45 System.out.println("CustomRuleA 选择好服务的端口="+instance.getPort());
46 return new NacosServer(instance);
47 }
48
49 return null;
50 }
51 }

user-service的配置文件

#指定当请求该服务时,所用的特定规则
blank-service.ribbon.NFLoadBalancerRuleClassName=com.nicebin.user.ribbon.rule.CustomRuleA

小结

本篇博客讲的都是比较零碎的Ribbon知识,具体的体系知识大家可以自己搜索,基本都是大同小异。看完了再结合博客进行补充也是不错的。Ribbon作为微服务的核心,很多组件能跟其结合(如Feign,网关等等底层都是调用Ribbon),所以了解Ribbon大致的原理就能让很多发送问题有了解决的头绪,希望能帮到大家啦。

Ribbon导航的更多相关文章

  1. VSTO 学习笔记(十)Office 2010 Ribbon开发

    原文:VSTO 学习笔记(十)Office 2010 Ribbon开发 微软的Office系列办公套件从Office 2007开始首次引入了Ribbon导航菜单模式,其将一系列相关的功能集成在一个个R ...

  2. Ribbon Workbench 与此流程相关的流程操作未激活

    问题描述:使用Ribbon Workbench 打开解决方案时报 :与此流程相关的流程操作未激活 解决方法 :ribbon 导航--系统定置--流程中心--流程--CustomiseRibbon -- ...

  3. 基于WPF系统框架设计(1)-为什么要仿Office2010 Ribbon?

    为什么系统框架设计使用Ribbon导航模式? 这得从Office软件的演变说起.微软为什么最后选择使用Ribbon,也许就是很多系统设计要使用Ribbon做功能导航的原因. 你是否还记得曾经使用过的M ...

  4. 【VS开发】VSTO 学习笔记(十)Office 2010 Ribbon开发

    微软的Office系列办公套件从Office 2007开始首次引入了Ribbon导航菜单模式,其将一系列相关的功能集成在一个个Ribbon中,便于集中管理.操作.这种Ribbon是高度可定制的,用户可 ...

  5. Nginx导航

    简介 最近都在弄微服务的东西,现在来记录下收获.我从一知半解到现在能从0搭建使用最大的感触有两点 1.微服务各大组件的版本很多,网上很多博客内容不一定适合你的版本,很多时候苦苦琢磨都是无用功 2.网上 ...

  6. Gateway导航

    简介 最近都在弄微服务的东西,现在来记录下收获.我从一知半解到现在能从0搭建使用最大的感触有两点 1.微服务各大组件的版本很多,网上很多博客内容不一定适合你的版本,很多时候苦苦琢磨都是无用功 2.网上 ...

  7. Sentinel导航

    简介 最近都在弄微服务的东西,现在来记录下收获.我从一知半解到现在能从0搭建使用最大的感触有两点 1.微服务各大组件的版本很多,网上很多博客内容不一定适合你的版本,很多时候苦苦琢磨都是无用功 2.网上 ...

  8. SharePoint 2013 开发——开发自定义操作APP

    博客地址:http://blog.csdn.net/FoxDave 自定义操作即我们所说的Ribbon和ECB(Edit Control Block),在SharePoint 2013之前,我们可以 ...

  9. ribbon 收起 最小化 导航条 选项卡 navBarControl 隐藏

    //设置隐藏导航条 this.ribbonControl.Minimized = true; 正解 //设置navBarControl隐藏 navBarControl.OptionsNavPane.N ...

随机推荐

  1. 技术分享PPT整理(二):C#常用类型与数据结构

    这篇博客起源于我对Dictionary.List.ArrayList这几个类区别的好奇,当时在改造公司的旧系统,发现很多地方使用了ArrayList,但我们平时用的多是泛型集合List,改造的时候要全 ...

  2. 力扣 - 剑指 Offer 09. 用两个栈实现队列

    目录 题目 思路 代码 复杂度分析 题目 剑指 Offer 09. 用两个栈实现队列 思路 刚开始想的是用stack1作为数据存储的地方,stack2用来作为辅助栈,如果添加元素直接push入stac ...

  3. C++并发与多线程学习笔记--多线程数据共享问题

    创建和等待多个线程 数据和共享问题分析 只读的数据 有读有写 其他案例 共享数据的保护案例代码 创建和等待多个线程 服务端后台开发就需要多个线程执行不同的任务.不同的线程执行不同任务,并返回执行结果. ...

  4. 【ProLog - 3.0 进阶:递归】

    [ProLog中的递归] 如果递归中的一个或多个规则引用谓词本身,则对该谓词使用"递归"定义 在使用时,这往往像一条食物链或者族谱的构成(A的爸爸的爸爸,即A的爷爷,是A的长辈) ...

  5. python导入数据的几种方法

    以下是在我学习过程中常用的两种导入数据的方式 方法一: c = open('ML2017Data/testTarget.csv',"r") file = csv.reader(c) ...

  6. .NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决

    前言: 前段时间在对接第三方接口的时候发生了一个非常奇葩的问题,就是使用 .NET Framework 4.6 HttpWebRequest进行网络请求的相关问题.背景,关于调用第三方的接口都是使用使 ...

  7. gateway调用Fegin失败问题解决

    起因 新项目用的是springcloud2.0,网关用gateway替换了zuul. gateway动态路由跟zuul有本质上的区别.这就涉及到webflux这一套大东东了.简单来说,gateway是 ...

  8. ReentrantLock理解

    原文出处:http://www.yund.tech/zdetail.html?type=1&id=ef94715a2838f06ab03b8621c23d1613 作者:jstarseven ...

  9. 持续集成 简介&环境搭建

    1. 持续集成简介 2. 持续集成环境搭建(Jenkins) 2.1 Git 安装 2.2 JDK 1.8 安装 2.3 Tomcat 安装 2.4 Maven 简介和安装 2.5 Jenkins 安 ...

  10. Python 基础教程 —— 网络爬虫入门篇

    前言 Python 是一种解释型.面向对象.动态数据类型的高级程序设计语言,它由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年.自面世以后,Pytho ...