微服务性能调优

近期遇到一些技术问题,记录如下:

1、kafka并发处理量上不去
数据流:
数据生产服务-》kafka-》数据消费服务
表现:
数据消费服务加了很多个实例,但总感觉多数实例不工作
原因:
分析后发现,原来开发小伙伴把所有消息都扔到了同一个topic中,而分区只有3,消费者再多这并发量也上不去啊
解决:
按不同业务,拆分topic,同时增加分区数
同时,建议把一堆操作拆分为多个步骤进行,不要都放到一个方法里全部做掉,宁可多流转几次各司其职

2、数据上报并发处理量上不去
数据流:
DB-》轮询-》HTTP提交数据到数据上报网站【ZF】
表现:
要求4小时上传60W,实际1小时上传5K
原因:
问题很多,主要有两个,一是每次只上传一条数据,二是没有做并发
解决:
一开始准备做很大的调整,但后面项目组怕把开并发把数据上报网站压挂,最后没敢使用
最后,只是改造为批量上传数据,轮询时根据id做了一下简单的并发
数据上报网站,各地接口及要求各不一样,也是各种不容易吧

3、莫名奇妙的403
数据流:
浏览器-》网关-》鉴权服务
表现:
网关偶尔返回403
原因:
一开始日志输出太少,都没有定位到哪里的问题,只能临时在网关补充了一些日志【建议加了开关,定位问题后关闭】
加日志后,发现是一段上古代码,使用信号量进行了并发控制,超出了并发就获取不到用户权限。
而这个Bug暴漏出来,据反馈,居然是升级组件导致的。
遗留系统都是坑啊。
解决:
优化鉴权服务,定位到问题,问题也就解决了

4、无法提升的微服务性能
数据流:
浏览器-》网关-》N个服务来回调用
表现:
服务性能差,有时要几十秒才返回,一堆告警邮件
原因:
微服务拆分粒度太细,形成环状调用链路
开发同学无脑调用微服务,能调用一次的,居然会循环调用N次
解决:
重构,按业务领域合并微服务,微服务数量少了60%,同时干掉环状调用链
评审,找到不合理的循环调用,抓典型,整改

5、批量导出
数据流:
浏览器-》网关-》导出服务-》DB
表现:
批量查询、批量导出性能很差,要按分钟返回的,一堆告警邮件
原因:
数据量太大,DB拉取速度慢,数据回传也慢
解决:
根据业务情况,部分批量查询功能改到只读库查询,大批量导出功能迁移到了数据中台

6、数据批量下发
数据流:
数据中台-》kafka-》数据下发接收服务
表现:
数据中台下发数据,无法更新到下游业务系统
原因:
因安全需求,上游业务系统批量刷新数据库,导致数据中台下发大量数据,数据下发服务处理不及时,积累了大量数据待处理
下游业务系统把一堆业务逻辑放到了接收服务中,处理单条业务数据要按秒计算,数据越积越多
你没想错,kafka并发上不去,和之前原因一样一样的
解决:
接收服务简化,拆分不必要的业务逻辑,服务性能提高了几百倍
优化kafka配置
制定了批量刷新数据库的相关流程,都是泪
历史数据咋处理?和上游系统沟通后,99.9%的数据不必处理,于是忽略了历史积累数据,晚上将0.1%的数据进行了重推,解决了问题

整体经验:
1、微服务粒度不能太细,也不能一个服务啥都干,最好按业务领域进行拆分。业务量小的领域可以适当合并,业务逻辑复杂的考虑拆分。
2、微服务也应该分层次,不要出现环状调用链路
3、日志要足够判断问题所在,太多影响性能,太少没啥用
4、中间件不能熟练配置,不要随便上生产
5、批量操作要用特殊处理方式,没事别刷库

一次数据库字段加密升级记录

今年个保法发布了,根据安全团队要求,需要对数据库的敏感字段进行加密处理。

当前数据库连接已经加密了,只需要对数据加密。有两种代价较小的方式:
1、在数据库存储引擎层面加密,这样对全部业务系统是无感的。
2、退而求其次,可以在数据库中间件或在驱动层面做加密,这样全部业务系统修改量也是比较小的。
但由于种种原因,这两种方式都没有能推行。

最后采用的方式是,安全团队提供加解密SDK,各业务系统对接。
业务系统启动,通过加解密SDK从密钥分发服务器获取密钥-》写入数据库前加密、读取数据后解密
加密算法都是国密算法,包括对称加密及摘要算法。
这样全部业务系统都需要改造,而且批量操作效率也比较低。
优点是,即使别人攻破数据库,也拿不到明文数据。

改造过程也很痛苦:
1、注册APP ID,申请密钥
2、研发刷库工具
3、在数据库表中增加加密字段,通过刷库工具,将历史敏感数据进行加密,存放到加密字段
4、基于加解密SDK,研发适用于个团队的切面SDK
5、使用切面SDK,对服务进行改造,读明文,写明文+密文(可跳过)
6、使用切面SDK,对服务进行改造,读密文,写明文+密文(可跳过)
7、使用切面SDK,对服务进行改造,读密文,写密文(可跳过)
8、删除明文字段
整个过程十分痛苦。

稳定性保障:
整个密钥下发服务器,是全局的一个大故障点,必须保障可用性。
密钥分发服务器,用到了密码机,提供了同城容灾及异地容灾环境。
支持DC单独部署,也支持云访问。

对应用系统影响:
1、改造量大,且无直接业务收益,资源投入受限
2、性能下降,尤其是批量加解密时,性能下降较多
3、模糊查询受影响较大,只能通过提前计算的摘要信息进行查询了
4、遗留系统、外购系统,改造难度太大,成本太高,无法承受

对数据中台的冲击:
所有依赖于数据库日志的系统,都会受到影响,尤其是数据中台
有两种方式,一是不使用,二是用同样的key

一次技术中台升级记录

由于历史原因,我们有两套技术架构:
基于SpringBoot1.X的老框架、老技术中台、老数据中台。
基于SpringBoot2.X的新框架、新技术中台、新数据中台。

老技术中台研发的时候,整个生产环境都是我们自己搭建的,很多功能需要自研。
到了新技术中台时,已经迁移到了集团的云上,之前设计的很多功能也就用不到了。
而且,随着时间的推移,老中台人员都去参与了其他项目,长期处于支持维护状态,无论研发、运维还是安全同事,都感到压力山大。
由于云端环境时不时会做调整,运维同学都不敢轻易重启老中台服务,怕一重启,就再也起不来了。
安全扫描策略也不断升级,扫描出来的问题一次比一次多,很快就千疮百孔了,但大家也只能缝缝补补。

之前由于业务压力异常巨大,大家一直在忙着做各种新的业务功能,虽然一直想升级,但一直没有狠下心来。
到了今年四季度,遇到了几次生产事故后,大家痛定思痛,决定还是干吧,把老中台下掉。

整体步骤大体如下:
1、找了两位对老技术中台比较熟悉的同事,对全部服务进行了梳理
2、各技术团队,也对老中台的依赖关系重新进行了梳理
3、大家坐下来,对服务进行了分类
A、对于网关类服务,按领域拆分
B、对于调用中转类服务,已经不符合当前要求,改为K8S的微服务直连
C、先看调用量小的服务;没有调用量的服务及接口,尽早下线
D、其余调用量很少的服务,与业务方沟通,能下线下线,不能下线合并等待下线
E、新老技术中台都有的服务,新中台进行适配,下线老中台服务
F、老中台有,新中台没有的中台类服务,功能迁移,下线老中台服务
G、非中台类服务,拆分到业务系统,下线老中台服务
H、其余服务,一事一议
4、对新老平台都保持的数据,进行数据治理,统一数据标准
5、在服务迁移改造的过程中,要求按新框架规范,将服务升级到SpringBoot2
6、由于没有业务上的直接收益,所以整个改造周期排了很久,各团队根据实际情况,在每次迭代中把工作量消化掉
7、及时与测试同学沟通,确保每次测试覆盖到
8、与运维同学沟通,服务全部升级完成后,切换nacos到最新版本(之前受限于SpringBoot1,无法升级nacos)
9、这样框架、技术中台就升级完毕了,后面每半年升级一次框架就可以了
10、数据中台的小伙伴,因形势所迫,直接抛弃了原有技术栈和工具,拥抱了新技术栈,最后技术债务居然是最小的。

任务已排期,各团队都表示坚决支持。但你以为这样就能顺利推进吗?我感觉比较难哦。
过半年,再续写一下,推进情况究竟如何,敬请期待。

秒杀及大促系统关键点

一、电商秒杀场景
0、尽早做好各相关团队的沟通,做好活动动员工作
1、搭建单独的秒杀系统,与核心交易系统隔离
2、做好静态资源缓存:浏览器、CDN、服务器缓存
3、通过JS,动态下发大促页面,大促抢单URL到秒杀时刻后才能下发
4、网关随机刷掉大部分用户,小部分进入到服务器,每台服务器只处理前N条数据,后续用户秒杀失败
5、redis分布式锁确保不会超卖
6、秒杀成功后,请求发送至核心交易系统
7、做URL验证,防止刷单
8、网关控制同IP流量,屏蔽部分云服务器IP段,防止部分刷单行为
9、提前做好性能测试及压力测试

二、电商大促场景:
0、尽早做好各相关团队的沟通,做好活动动员工作
1、业务上分时段大促,不同商品分流,缓解服务器甚至快递小哥压力
2、做好静态资源缓存:浏览器、CDN、服务器缓存
3、根据过往流量、商品浏览量、购物车商品数量,估算大促流量
4、做好扩容和运维保障工作:服务器、带宽、数据库根据预测流量,进行弹性扩容,而且要有一定比例的富余量
5、大促商品信息提前加载redis缓存
6、引入MQ,异步处理订单,消除业务峰值
7、做好PlanB,限流、降级、熔断,保证核心业务稳定
8、网关控制同IP流量,屏蔽部分云服务器IP段,防止部分刷单行为
9、提前做好性能测试及压力测试

打车软件功能拆解

一个打车软件,基本需要以下功能:

一、乘客:
1、行程管理:乘客叫车、行程取消、历史行程查看
2、乘客上车引导
3、乘客与驾驶员聊天功能
4、乘客与驾驶员虚拟电话沟通功能
5、行驶轨迹展示、规划行驶路线展示
6、目的地修改
7、乘客支付
8、打赏功能
9、驾驶员评价功能
10、投诉功能
11、消息通知
12、紧急联系人,一键报警,行程分享

二、驾驶员:
1、车辆开始接单,车辆停止接单
2、车辆实时位置信息推送
3、抢单、订单查看、订单取消
4、车辆到达确认
5、驾驶员与乘客聊天功能
6、驾驶员与乘客虚拟电话沟通功能
7、乘客上车确认,开始计费
8、结束计费
9、乘客评价功能
10、收入查看、提现
11、申诉
12、消息通知

三、平台:
1、地理信息系统与车辆网格划分
按GeoHash将城市划分为多个网格,收到车辆位置后,将车辆更新到各个网格;
2、平台派单
根据乘客起始地点,在乘客所属网格,就近派单;
考虑用户习惯,价格、车况等;
不能让乘客长久等待,适时给驾驶员奖励;
给同一驾驶员单子要有好有坏;
不同驾驶员要雨露均沾,不能造成饥饿状态;
不同业务要用派单或抢单模式;
3、行驶路线规划
4、等待时长预估
5、计费规则设置、计费功能
6、车辆位置采集,车辆轨迹记录
7、车辆在线时长统计,车辆收入及行程数统计
8、发票管理、行程单管理
9、客服系统,客诉处理,工单系统对接
10、消息通知:
短信、微信、APP
11、信用系统:
乘客信用
驾驶员信用
黑名单
车辆信息审核
驾驶员信息审核
12、标签系统:
乘客标签及画像,个人乘车偏好
车辆标签及画像
驾驶员标签及画像
13、行驶安全:
驾驶员疲劳管理;
防疫信息管理;
行程录音取证分析;
AI自动分析异常情况,识别争吵、车辆路径偏离,车辆长期不移动等情况;
紧急情况处理,安全人员及警方及时介入,通知乘客安全联络人;
14、基础数据管理
用户、权限、角色、组织、城市、车辆管理、驾驶员管理
15、外部对接API
订单接收,订单确认或取消,行程推送,行程状态同步,计费推送,费用结算

四、业务扩展:
1、市场营销:卡券管理、优惠活动
2、增值业务:保险售卖、加油卡售卖
3、在专车之外,可以开展出租车、顺风车、拼车、预约用车、代驾、企业用户等业务
4、入口从APP扩展到公众号、小程序、其他打车平台、电话

为何技术人员要懂业务



为何技术人员要懂业务
By NEOHOPE

公司是脚,业务是穿鞋的场景,技术是鞋子。

先考虑技术,再考虑业务,往往会导致削足适履,让你怎么穿都别扭;
不考虑技术,只考虑业务,会导致打赤脚或穿草鞋,让你天天肉痛。
两者一起考虑,才能找到合适你的跑鞋、登山靴或轮滑。

不懂业务的技术人员,很难设计出一双适合用户的好鞋子;
不懂技术的业务人员,至少知道用户要一双什么样的鞋子。
所以,你不懂业务,技术再牛,也要听懂业务的。

一句话,除非你是搞理论研究或专业分工的,否则,脱离了业务说技术都在是耍流氓,脱离了业务谈架构同样是在耍流氓,脱离了业务天天扯一堆前沿名词就是大流氓。

工作笔记001

Hansen的工作笔记001

最近,根据工作安排的调整,参与了部分售前支持工作,发现了工作上的一些不足之处:
1、个人对公司产品的理解不够深入,对用户的最关心的痛点理解过于肤浅,对行业态势了解滞后,对竞争对手了解太少。
2、公司产品的相关文档太少,苦了售前、实施各位大哥大姐。
3、沟通时,技术性仍然太强。回想起来,用户、售前和销售人员居然表示可以理解,也太难为他们了。后面要做到,对方不懂技术,也可以讲明白。
4、有时候,过于急躁,看到自己写的“戒骄 戒躁 戒懒”的便利贴,还是脸红了一下。

改进措施:
1、多学习。就像前面和杨荣聊的,人懒了,放弃学习了,也就掉队了。你做软件,做不到35,除了自己谁也别怪,只能怪自己。
2、多沟通,多讨论。沟通和讨论,是一个很好的可以帮自己系统梳理思路的好方式,关键是不累心。
3、知识组成要多元化。团队成长到一定阶段,即需要专精人才,也需要综合性人才。要及时找到适合自己的路子。但即使你走专精的道路,也要让自己的知识构成多元化一些,才不至于闭门造车。
4、搭建了OpenKM,替代了没人用的Wiki。希望可以发挥一些作用。感谢陈燕婷的大力支持。
5、要逼着各位产品经理、技术经理补充缺失的文档。相信对他们也有很多好处。
6、加强个人非技术的沟通技巧,文档写的要让非开发人员可以读懂。

公司SOA架构演化

最开始的时候,公司没有采用任何SOA架构。
(虽然用到了COM,但没有用到DCOM)
(用到了SOAP,但仅仅是做接口使用)

2011年,开始用EJB,但只在一个项目使用了EJB。

2012年,突然涌进了大量的接口,于是求救于ESB,成为了下面的样子。
ESB+SOAP
ESB+HL7
ESB+REST

2015年,开始向RPC框架求救。
ESB+Dubbo+(SOAP/REST/HLU)

浏览器插件的演化

浏览器插件,主要使用了两种,一种是微软的ActiveX插件,一种是Java Applet。

说实话,两种插件的引入,主要是为了突破浏览器的本地访问限制。而且,很多控件都是内网使用,是自签名的,你懂的。

ActiveX插件,主要用于了调用WindowsAPI,调用本地EXE等。
这种模式,在2013年-2014年,逐步被CS+BS的模式所替代。

Applet插件,主要用于了多线程下载控制,调用JS等。总体来说,JVM对Applet的沙盒控制还是越来越严格了。
在2013年引入了Java Web Star,但效果也一般。

BS架构的演化

==========================================================
2010年下半年,公司开始BS开发,主要语言为java。以Sevlet+JSP为主,只用了Struts1框架。

2011年,引入三大框架Struts2、Hibernate、Spring。

2012年-2013年,以后台通信业务为主,主要使用了Hibernate、Spring。负载均衡采用了APACHE+TOMCAT的方式。

2013年-2014年,引入了Maven及模块式开发,引入了ESB,开始推行单元测试。Struts2逐步切换到SpringMVC,Hibernate逐步切换到MyBatis,并进行了二次封装。

2015年,引入监控机制,版本发布机制,开始抽离SQL语句。引入Reids+Nginx,引入MongoDB,引入消息中间件。

2016年,引入CI,引入eXistDB。

==========================================================
自从2010年开始使用C#以来,也有不少BS项目是C#开发的。

2010年-2014年,主要采用ASPX+ADO.net的开发模式。

2015年,引入了EntityFramwork+MVC的开发模式

2016年,引入单元测试及CI。