[Java复习]架构部署 超时重试 幂等防重
画一下你们系统的整体架构图,说说各个服务在生产环境怎么部署的?
核心:服务框架、注册中心、网关
即使你没有用很多微服务架构里的东西,只要有上述三个东西,配合上写一些文档,接口文档,分布式系统架构,其实就出来了,很多中小型公司,一个小型技术团队,后端开发工程师总共就10多个人。
常见生产实践问题:
关注分布式系统一些生产实践的问题,应对你们公司的流量,各个服务、网关、注册中心,都是如何部署的?
部署几台机器,每台机器的配置是什么,每天整体的流量有多少,高峰期的请求量有多少,你的整体系统是否抗住了?
各个服务之间的超时、重试、幂等性?
中小型系统,拆分10-20个微服务。大型互联网公司,一般几百个,几千个微服务。
中小型,一般2-3台机器足够,把服务上线,服务发现优化到极致。
服务上线:注册表多级缓存同步至1秒,拉取频率降低至1秒。
服务心跳:1秒报1次。
故障发现:1秒检查一次,2,3秒没有认为没有故障等。
服务注册中心没有压力,服务注册中心部署2台机器,每台4C8G,高可用,每秒轻松几百请求,甚至上千。前提是数据库SQL别写的太烂。
网关机器配置稍微高一些,4C8G,一台扛每秒几百个请求,部署3~4台,保证每台网关机器压力较小,进一步保证可靠性。
为什么网关Zuul之前还要配置Nginx?
Nginx反向代理,软负载,把请求均匀负载到多台Zuul的机器上。LVS和Nginx处于不同的负载维度,主要是运维工程师负责管理。
数据库,MYSQL,16C32G,物理机最佳,平时扛每秒几百请求,高峰期最多每秒扛三四千请求。
扛几千请求时机器会负载很高,CPU,IO,网络负载很高。DBA在优化一下。
你们系统每天有多大访问量?每个服务高峰QPS多少?压测过服务最大QPS吗?
每天服务多少请求量,高峰每秒qps,在代码里稍微加一些metrics代码,对自己运行过程中各种请求量,每秒请求量,成功次数,失败次数,在内存里直接做一些计数。
在负责的核心服务里,核心接口,开发一个简单的metric统计机制,AtomicLong,保证原则性,并发数据统计准确。
每个接口被调用时,可以对每个接口每分钟做一个metric统计,每个接口每天统计计数。
再通过Log4j, logback等日志组件,把次数直接打印到日志文件,统计出高峰期每秒系统被访问的次数,每条每个接口访问量。
响应延时:
计算一下每个接口从请求到执行完毕,需要耗费多长时间,算一下每个接口平均的请求延时,
TP99,TP95,TP90,TP50,TP99,99%的请求耗费的时间在100ms以内,但是1%的请求可能耗费的时间在100ms以上
TP99 = 100ms TP95 = 50ms,95%的请求耗费的时间多在50ms以内,但是5%的请求耗费的时间在50ms以上
压测工具,java压测工具,开源的可以用的,模拟出来同时有多少用户发起多少请求,每秒发起1000请求能抗住吗?每秒钟发起2000请求能抗住吗?
假设你的系统每秒钟最多抗800请求,如果你的压测工具每秒发起了1000个请求,此时会发现最多只有800个请求同时可以被处理,
剩余200个请求需要进行排队被阻塞住了,表示你这个系统每秒钟最多抗800个请求。
如果系统访问量比现在增加10倍,你们考虑过系统的扩容方案吗?
网关直接多部署10倍的机器即可,前面的Nginx做会负载均衡,把流量均匀分发给各个网关机器。
服务扩容,都很简单的,多加机器,部署启动,自动注册到注册中心去,此时其他服务会自动感知到你的服务多加了一些机器。
服务实例变多了10倍,此时几十个服务实例,几百个服务实例,对eureka机器会造成每秒几百请求,没问题,eureka机器,8核16G的配置,单机抗上千请求,很轻松。
数据库本来是每秒几百请求,10倍,每秒高峰期是三四千请求,横向扩容很麻烦,
此时可以考虑给单个数据库部署的机器提高配置,32核128G高配物理机,每秒钟抗几千请求问题不大。
总结: 最基本的操作就是扩容。
网关:横向加机器。
注册中心:纵向升配置。
数据库:纵向升配置。
当然还有很多其他专门针对分布式,高并发的优化和操作,不过加机器都是最简单直接的。
你们生产环境的服务是怎么配置超时和重试参数的?为什么要这样配置?
背景:Spring Cloud生产优化,系统第一次启动的时候,调用请求经常出现timeout。
原因:每个服务第一次被请求的时候,他会去初始化一个Ribbon的组件,初始化这些组件需要耗费一定的时间,所以很容易会导致超时。
解决方案:让每个服务启动的时候就直接初始化Ribbon相关的组件,避免第一次请求的时候初始化。
ribbon:
eager-load:
enabled: true zuul:
ribbon:
eager-load:
enabled: true feign:
hystrix:
enabled: false
线上的服务,每个服务部署上线的时候,一般来说都需要配置相关的超时时间还有重试次数
订单服务 -> 积分服务、库存服务、仓促服务
订单服务对于其他服务的调用,一般来说限制在多长时间就必须认为是超时了,如果超时之后如何进行重试
积分服务部署了两台机器,机器1和机器2
订单服务在一次请求积分服务的机器1的时候,超过1秒钟,超时了;此时需要进行重试,对积分服务当前的这台机器1重试几次?如果说机器1不行,是否可以重试一下积分服务的机器2?
ribbon:
ConnectTimeout: 3000
ReadTimeout: 3000
OkToRetryOnAllOperations: true
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 1
中小型的系统,没必要直接开启hystrix,资源隔离、熔断、降级,如果你没有设计好一整套系统高可用的方案。
增加重试机制依赖:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
如果出现服务请求重试,会不会出现类似重复下单的问题?
可能会。
订单服务 -> 创建订单 -> 库存服务 -> 扣减库存 -> wms服务 -> 通知发货 -> 积分服务 -> 增加积分
场景:
订单服务调用库存服务的时候,因为网络抖动,请求超时了,超过了秒钟,此时订单服务会重试,再次调用一下库存服务,发送一模一样的请求过去。
比如说,订单服务第一次请求库存服务,库存服务其实是把扣减库存的业务逻辑执行成功了,
只不过网络问题,导致响应迟迟没有返回给订单服务,可能在1.2s之后返回了响应给订单服务。
订单服务就认为请求超时了,他就再次发送了一个一模一样的请求给库存服务,库存服务可能会再次对库存进行扣减。
对于核心接口的防重幂等性,你们是怎么设计的?怎么防止重复下单问题?
常见方案:
1. 数据库唯一索引
2. 基于Redis实现幂等性防重
核心接口,幂等性都是自己保证,对应Create操作,通过DB唯一索引来保证;对于Update操作,建议在核心接口基于业务逻辑,配合Redis,来保证幂等性。
比如库存,定制化的针对接口开发幂等性的机制,比如说一旦库存扣减成功之后,就立马要写一条数据到redis里去,order_id_11356_stock_deduct,写入redis中,如果写入成功,就说明之前这个订单的库存扣减,没人执行过。
但是如果此时有一些重试的请求过来了,调用了你的库存扣减接口,他同时也进行了库存的扣减,但是他用同样的一个key,order_id_11356_stock_deduct,写入redis中,此时会发现已经有人写过key,key已经存在了。
此时你就应该直接对刚才的库存扣减逻辑做一个反向的回滚逻辑,
update product_stock set stock = stock - 100,update product_stock set stock = stock + 100,反向逻辑,回滚自己,避免重复扣减库存。
参考资料:
21天互联网Java进阶面试训练营(分布式篇)-- 中华石杉
[Java复习]架构部署 超时重试 幂等防重的更多相关文章
- dubbo超时重试和异常处理
dubbo超时重试和异常处理 dubbo超时重试和异常处理 参考: https://www.cnblogs.com/ASPNET2008/p/7292472.html https://www.tuic ...
- Java Web架构总结
转载至:http://www.cnblogs.com/wuxl360/p/7489763.html 初始搭建 开始的开始,就是各种框架一搭,然后扔到Tomcat容器中跑就是了,这时候我们的文件,数据库 ...
- [Java复习] 分布式PRC - Dubbo
分布式RPC框架 dubbo常见问题: 1. 问dubbo的工作原理:服务注册,注册中心,服务生产者,消费者,代理通信,负载均衡 2. 问网络通信,序列化: dubbo协议,长连接,NIO,hessi ...
- 图灵学院JAVA互联网架构师专题学习笔记
图灵学院JAVA互联网架构师专题学习笔记 下载链接:链接: https://pan.baidu.com/s/1xbxDzmnQudnYtMt5Ce1ONQ 密码: fbdj如果失效联系v:itit11 ...
- JMicro微服务之超时&重试
JMicro是本人开发的基于Java实现的微服务框架,当前正式版本为0.0.3,并已发布到maven中央仓库.项目源码github:https://github.com/mynewworldyyl/j ...
- paip.提升用户体验--提升java的热部署热更新能力
paip.提升用户体验--提升java的热部署热更新能力 想让java做到php那么好的热部署能力 "fix online"/在线修复吗??直接在服务器上修改源码生效,无需重启应 ...
- Java应用架构的演化之路
Java应用架构的演化之路 当我们架设一个系统的时候通常需要考虑到如何与其他系统交互,所以我们首先需要知道各种系统之间是如何交互的,使用何种技术实现. 1. 不同系统不同语言之间的交互 现 在我们常见 ...
- java企业架构 spring mvc +mybatis + KafKa+Flume+Zookeeper
声明:该框架面向企业,是大型互联网分布式企业架构,后期会介绍linux上部署高可用集群项目. 项目基础功能截图(自提供了最小部分) 平台简介 Jeesz是一个分布式的框架,提供 ...
- 15套java互联网架构师、高并发、集群、负载均衡、高可用、数据库设计、缓存、性能优化、大型分布式 项目实战视频教程
* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展 ...
随机推荐
- Git操作:使用.gitignore来管理VS工程
在使用Git管理Visual Studio的工程时,经常会碰到这种情况: 整个工程文件夹有100多M,而源代码只有100多K.如果全部添加进Git,那每次编译时产生100M垃圾,10次Git提交就会使 ...
- 数组和list 相互转换中遇到的坑
代码示例: public class ArrayDemo { public static void main(String[] args) { Integer[] arr = {1, 2, 3, 4, ...
- 【转】linux自测题
一.填空题: 1. 在Linux系统中,以 文件 方式访问设备. 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 来标 ...
- linux修改网卡的mac地址
linux在安装一些软件的时候可能会用到修改主机的mac地址的问题,在网卡配置文件 /etc/network/interface 中添加mac地址的方式我在修改重启机器后没有生效,所以采用其他方式 在 ...
- Jmeter 处理接口乱码
第一步:添加 BeanShell Listener 第二步: 设置值 : prev.setDataEncoding("UTF-8") 第三步: 重新跑脚本,看接口返回值
- BurpSuite多重代理的情形
有时候为了隐藏自己的真实IP,访问目标网站需要走代理.比如说,通过代理IP访问目标网站并且代理IP可以随时切换,这样可以避免IP被封堵后无法访问目标网站的尴尬. 一. 首先把代理切换为全局模式 操作步 ...
- Java 合并多个文件内容到一个文件(递归遍历某个文件夹下所有文件)
这段代码通过Java I/O流API实现将多个文件合并到一个文件中,输出为文本文件,提供一个支持语法高亮的网站,http://www.codeinword.com/ 适合粘贴代码到word文档,小巧实 ...
- SMB远程代码执行漏洞(CVE-2020-0796)分析、验证及加固
这几天有点忙,CVE-2020-0796出来了,没静下心来关注一下,显得太不尊重这个漏洞了,今天周末,关注一下,水一篇. 一.漏洞描述 漏洞公告显示,SMB 3.1.1协议 ...
- 探究:nuget工具对不再使用的dll文件的处理策略
背景介绍 nuget是.net平台有效的包管理工具,相信每个C#开发者对它都不陌生. 本文我们来探究一下nuget对不再使用的dll文件的处理策略,分为如下2个场景: 场景A:包A1.0原来包含New ...
- 自学linux——8.firewall-cmd的命令使用
firewall-cmd使用方法 1.firewall-cmd的含义 firewall-cmd 是 firewalld的字符界面管理工具,firewalld是centos7之后版本的一大特性, 最大的 ...