怎么编写可持续发展的代码

怎么编写可持续发展的代码?

规模垂直扩张

规模垂直扩张, 指的是提高同一个处理单元处理更多负载的能力。 比如, 硬件上, 增加服务器的
硬盘、 内存和CPU; 软件上, 优化算法、 程序和硬件的使用等。
规模垂直扩张是传统的提高负载的方式, 方式方法都比较直观, 效果也立竿见影。 但是, 规模垂
直扩张成本很高, 而且是非线性的。 比如说, 4倍的CPU可能只提高2倍的负载, 而8倍的CPU可
能只提高2.5倍的负载。
另外, 规模垂直扩张是有上限的, 一台服务器的处理能力不是可以无限扩展的。 还有, 硬件的规
模扩张, 可能要更换机器, 停止软件运行。 这种规模扩张方式, 不太适用于可用性要求高的产
品。 比如我们常用的微信, 出现5分钟的停机都是天大的事故。

规模水平扩张

规模水平扩张, 指的是通过增加更多的处理单元, 来处理更多的负载。 我们常见的例子, 就是增
加服务器。 分布式系统、 负载均衡、 集群系统这些技术, 提供的就是规模水平扩张的能力。
优秀的规模水平扩张技术, 可以使用很多廉价的机器, 提供大规模的计算能力。 一般情况下, 规
模水平扩张的成本要低于规模垂直扩张。 而且, 如果其中一个节点出了问题, 只要其他节点还在
正常工作, 整个系统也可以照常运转。 如果想要添加一个新节点, 系统也不需要停顿。 规模水平
扩张技术的这些特点, 非常适用于高可用性系统。
和规模垂直扩张相比, 规模水平扩张的方式方法并不直观。 支持规模水平扩张的代码要能够协调
地运行在不同的机器上, 也就是说要支持分布式计算。 很多代码, 不是天生就支持分布式计算
的, 而且修改起来也不容易。
我们常说的优化代码, 一般指的是提高每一个处理单元的使用效率, 也就是规模垂直扩张能力。
其实, 我们还要考虑代码是不是能够分布式运行, 也就是规模水平扩张能力

麻烦的状态数据

影响代码水平规模扩张的最重要的一个因素, 就是用户的状态数据。 比如, 用户的登录状态, 用
户购物车里的商品信息, HTTP连接里缓存的会话数据等。
如果用户访问一个服务节点时, 在节点留下了状态。 这个状态就要在多个节点间同步。 否则, 如
果用户下一次访问被分配到不同的服务节点, 这个状态就会消失不见。 比方说吧, 上午, 我们在一个网站购物, 把待选的商品放到购物车里。 这个选择商品的过程, 可能是由位于北京南城的数
据中心的一台服务器处理的。 下午, 我们准备结账, 重新访问这个购物网站。 这时候, 服务器可
能是由位于贵州的数据中心提供的。 如果上午访问和下午访问的服务器之间没有同步购物车数
据, 下午访问时, 购物车里就没有我们想要的信息了。
购物车的状态同步, 可以通过分布式数据库来解决。 分布式数据库自动处理多个节点之间的数据
同步。
现在的软件服务, 大都是基于HTTP协议提供的Web服务。 Web服务本身就是一个无状态的协
议。 即使可以保持HTTP的连接, 一般的服务框架也会考虑在连接不能保持情况下的会话管理,
也就是保存用户状态。 HTTP协议层面的状态管理, 也需要支持分布式计算。 搭建支持规模水平
扩张的Web服务时, 要做好Web服务框架的选型。
如果我们的代码里, 保存了状态数据, 可能会影响规模水平扩张的能力。 比如说下面的这个例子
中的sessionCache这个静态变量, 如果用来保存用户的会话, 并且使用SessionId匹配用户行
为, 规模水平扩张时就会遇到麻烦。 因为, 这个变量内容的更改, 只存在于运行它的节点里, 不
能在一个分布式系统的每个节点之间同步。
对于规模水平扩张的需求, 状态数据是一个很麻烦的存在。 甚至, 一些基础的, 需要保存状态数
据的网络协议, 在早期的版本中也没有考虑规模水平扩张的问题。 这就给规模水平扩张带来了一
定的困难。
所以, 采用规模水平扩张时, 一定要小心代码的状态数据能不能同步。 另外, 由于软件依赖的基
础设施问题, 还要测试软件的运行平台是否能够很好地支持规模水平扩张

无状态数据

如果一个服务是无状态的, 规模水平扩张就会非常顺利。 比如说, 静态的网页, 静态的图片, 静
态的商品描述, 静态的JavaScript和CSS文件等等。 由于不需要在服务端保留状态, 这些数据资
源就不需要在不同的节点间实时同步。 无状态的数据, 可以降低规模水平扩张的技术复杂性, 在
技术上有了更多的改进空间。
比如说, 现代的浏览器, 都可以缓存静态数据, 比如说静态的JavaScript和CSS文件。 如果用户
访问的两个不同网站, 使用了相同的脚本文件。 浏览器只需要下载一次脚本文件, 就可以在两个
网站使用。 这样, 缓存的脚本文件就可以加速网页的加载, 减轻服务器的压力

分离无状态数据

由于无状态数据有这么多的优点, 把无状态数据分离出来, 单独提供服务就成了一个常用的解决
方案。 独立的无状态数据服务, 既没有规模水平扩张的羁绊, 还能充分利用客户端的缓存。 另
外, 无状态数据和状态数据的分离, 可以让状态数据的处理集中资源, 也能提高状态数据的处理
能力。
比如说, 一个网站如果使用了共享的jquery.js脚本, 下载这个脚本, 就不再占用这个网站的资源
了。
所以, 如果你要设计一个具有规模扩张能力的软件架构, 分离无状态数据和状态数据, 既可以提
高规模水平能力, 也可以提高规模垂直扩张能力。

使用用户资源

对静态数据进行缓存, 是现代浏览器提高服务性能的一个重要办法。 除此之外, 浏览器还可以缓
存动态数据, 比如HTTP的cookie以及HTTPS的安全连接的参数。
鉴于无状态数据的诸多优点, 一些协议设计开始考虑无状态的服务场景。 比如, TLS 1.3就加入
了对无状态服务的支持。
无状态服务, 并不一定都没有服务状态。 一个典型的做法是, 服务端通过一定的数据保护机制,
把服务状态保护起来, 发送到客户端。 然后, 客户端缓存封印的服务状态。 下次连接时, 客户端
把封印的服务状态原封不动地送回到服务端。 然后, 服务端解封客户端发送的封印服务状态, 就
获得了需要处理的状态数据。 这样, 既有了无状态服务的便利, 解除了规模水平扩张的限制, 又
解决了服务需要状态的客观需求。遗憾的是, 这种设计能够提供的服务状态数据尺寸比较有限, 应用场景也比较苛刻, 而且数据保
护机制一般也比较复杂。 所以, 我们一般要在基础架构层面解决掉核心的问题(数据保护机制、
服务状态封存机制、 缓存机制等) 。 然后, 在应用层面仅仅定制状态的内容, 比如HTTP的
cookie的格式和数据, 就是可以定制的内容。 而HTTP的cookie交换的机制, 就由HTTP协议负责
解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值