生产运行这么久了,我就抄了一下,能有什么风险?

咱们经常写业务代码时,如果用到了某个组件或者相似逻辑,有时候会从项目的其他地方抄一份改一改。有人会认为,这段逻辑在生产运行这么久了,是经过时间验证的。我就抄一下,快速完成任务即可,运行原理可以不用理解。

用成熟的逻辑本身没错。但要建立在自身理解的基础上。下面以实际场景为例,咱们来看看不理解的抄代码会引起哪些问题。

某业务为了实现kafka顺序消费,在消费端使用zookeeper的leader选举逻辑实现只有一个节点在消费消息,然后持久化到数据库。

7526384ecc5c9c52e5f70a4c1fce7a35.png

现在要新加一个消费者组,对另外一个功能实现持久化。因为从本质上来看,我们的业务并不需要严格的顺序消费,只需要保证新数据不被旧数据覆盖。因为kafka有offset等字段,本身可以知道哪是新数据,哪是旧数据。所以做方案阶段,我们的方案是采用redis分布式锁,有数据更新时,用分布式锁同步数据,在锁内判断哪是新的,哪是旧的。新数据可以覆盖旧数据,旧数据可以直接返回不用处理。这样,我们可以以集群的方式各节点平等的运行服务,实现了从主备模式到分布式模式的切换。

这个方案相比较原有方案的好处是:原有方案启动时借助zookeeper选主的过程很慢,测试发现要1分多钟才能选举成功,这个过程中消息会积压,甚至会丢失消息,需要在部署时检查是否需要手动重放消息。而新方案省去了选主过程,启动完即可提供服务;各节点平等运行,负载均衡,消息不容易丢失。

如果开发小哥哥实际开发时并没有按照方案设计来编码,而是直接将原有逻辑拷贝一份做修改,不仅仅是设计效果没达到的问题。

我们使用apache的curator客户端来使用zookeeper的功能,拷贝原有逻辑时本质会把下面代码也new一份

CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient(zookeeperHost, new RetryForever(2000));
curatorFramework.start();

就是说会新注册自己是一个leader选举的候选人参与leader竞选。就是说新开发的逻辑会与原有逻辑争抢leader,它抢成功了可以消费kafka消息。自己的逻辑看似没有问题。但是原来的服务就不工作了。

好在基础组件封装的时候,竞选leader的节点名没有用随机数、线程数等。因为本来就是为了一个服务器上只有一个这样的逻辑准备的,所以用了机器信息作为节点名注册的。所以恰巧两个都能工作。因为一个选成功了,另外一个因为跟原来那个重名,所以也认为自己是leader。

这就好像上网课。大家彼此不认识。今天老师表扬了班上的小明,因为班上有两个叫小明的,他们都只知道自己叫小明。所以都认为夸的是自己。实际情况并不是这样。

一旦注册命名逻辑改了,那就可能造成大事故。

后记

我在做code review的时候,会询问开发者对自己编写逻辑的理解情况。我还会检查开发者在测试时DB、redis、zookeeper等存储的数据是否符合预期。我会尽量避免编写要上到生产环境的代码。因为我自己写的代码也需要别人来把关。要避免既当裁判员,又当运动员。

提高生产效率的一个有效方法是生产不出问题。一个事故,从发现、解决到写事故报告,抛去生产的SLA指标,光时间上投入就非常大。这个时代,大家对技术好坏的评判也在升级。与其做一个救火队长,不如直接给咱们的运行环境带来和平稳定。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值