加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 创业 > 经验 > 正文

构建互联网高性能WEB系统经验

发布时间:2023-12-22 03:15:51 所属栏目:经验 来源:DaWei
导读: 无状态服务有时候不可避免的会遇到一些有状态的对象,比如最常见的就是session。因为http请求本身是无状态的,所以必须cookie和session配合使用,才能识别多次http请求属于同一用户。一般有
无状态服务有时候不可避免的会遇到一些有状态的对象,比如最常见的就是session。因为http请求本身是无状态的,所以必须cookie和session配合使用,才能识别多次http请求属于同一用户。一般有两种方法解决:

使用分布式session服务

第一种就是将对象信息全部存储在cookie中,通过相应的算法在服务端将cookie中的信息读出来。这些信息一般都会进行加密处理。

第二种方法,就是将session存储在分布式数据库或者分布式缓存中,一般存在redis或者memcache中。那么这种服务扩展会依赖第三方数据库缓存的能力。

无状态服务用到了拆分和缓存

业务拆分

无状态可以使应用服务水平扩展,但是当单个应用太大太臃肿时,有必要对应用进行拆分。垂直拆分即按业务拆分,比如电商系统中,按照订单系统,积分系统等进行拆分。拆分可以方便开发,更方便扩展。系统大了以后,每个业务的访问量是不一样的,比如买家系统肯定比卖家系统访问量大得多,这时候就可以增加买家系统的机器即可。

除了按照业务的不同拆分成不同的系统以外,针对我们的应用层也可以进行拆分,一般分为应用层、逻辑层和原子层。应用层就是各种数据、逻辑业务的组装,逻辑层含有大量可重用逻辑,原子层直接操作数据库,一些基本的数据操作包含在其中。

不论以何种形式拆分,拆分以后的系统在物理层面上就分离开来,所以系统间的通信是拆分中最重要的问题所在。

RPC

在RPC服务之前已经有许多系统通信的方法,比如RMI、WebService,但是RPC以更方便,更高效,跨平台的方式现在成为主流的通信手段。几乎每个大公司都有自己的RPC框架:淘宝的HSF、58的SCF,也有非常多优秀的开源框架:Dubbo、GRPC、Thrift等等。

MQ

RPC调用一般是用在耦合比较重要,同步调用的场景下。而MQ作为另一种异步通信的手段也被广泛使用在各个业务中。常用的有:ActiveMQ、RabbitMQ、Kafka、RocketMQ。前两个一般作为企业级应用,主要特点是支持非常多的特性和规范。后两者是互联网级的,拥有更强的吞吐量和更高的性能,但是牺牲了很多MQ的特性。mq一般用在要求最终一致性即可的场景,比如用户注册和发积分这两个动作,可以用户注册以后直接返回前台成功,然后发送注册成功消息给mq系统,发积分动作订阅注册事件,消费mq的事件信息。

MQ最大的好处就是削峰和解耦,在RPC的同步调用场景中,如果同一个逻辑中调用A和B,那么在扩展的时候,A和B一定是需要同时扩展的,但是有了消息以后,A发送消息给B,即使B暂时处理不了,也可以等到A峰值过后B继续处理,即使B短期无法匹配A的发送消息能力也没有关系。

数据库拆分

一般项目都会经历数据量从小到大的变化,所以数据库拆分也是根据不同的数据量以及不同的阶段进行相应的处理。

读写分离,这是大多数应用在遇到性能瓶颈时第一要干的事。大多数互联网应用都是独占道90%以上的场景。所以一主多从,一个master做写,其他slave做读即可。但是这种主存模式也存在一些问题,比如有一些数据需要及时性比较高,就是在写入以后马上需要读到。因为主从同步是通过log异步复制,所以会出现数据不一致的窗口,这时候就需要强制读主库,确保数据不被篡改,这在开发过程中,你一定要重视。

垂直分割,就是通过拆分将不同的业务放在不同的数据库中,这样就可以减少单一数据库的压力,提高整体性能。垂直分割要注意的是业务边界问题,边界问题就是有一个表,感觉放在A中和放在B库中都合适。这个就要靠经验了,不能过分的考虑,因为其实不论你在之前分得有多好,在应用的迭代中,总会出现更多的找不到明确边界的表。

水平分割,一般就是sharding。将同一个表中的不同字段,拆分成不同的表,或者将同一张表按照hash或者业务字段分成不同的分片。这种一般需要DAL框架的支持,其中有TDDL、Cobar、Mycat等。主要就是通过框架让程序编写者对数据库的拆分不可见,就像操作一个数据库一样。但是现在的DAL框架,却并不能实现上述目的,尤其是在跨库交易的场景下,一般来说,还需要用其它的方式来处理。

跨库事务/分布式事务

跨库事务一般都是通过最终一致性来解决,即不强求ACID都能满足,容许数据不一致的时间窗口,但是总会有一个时间点数据会达到最终一致的状态。其实各种的解决办法都非常的多,但是核心原理也都一样,无非就是要靠补偿来完成。

缓存的使用

计算机世界有一句名言:“计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决”。缓存就是一种中间层。

缓存一般有两种,local和remote,一般来说使用一种缓存即可,因为缓存虽好,但是维护缓存的更新和删除却是一件非常麻烦的事。一般缓存可分为读缓存(大多数场景)和写缓存(一般针对数据安全性比较低的场景)。

比如将数据库中的数据读出时同时写入缓存中,下一次读取数据的时候就可以直接读取缓存中的数据,从而大大减小数据库的压力,说起来很简单,其实这也存在很多种的架构,每种架构都有利弊,大家可以详细去了解。

缓存虽然速度快,除了维护更新较为麻烦的,内存也是较为昂贵的硬件,所以除了将热点数据存储在缓存中,一般缓存中维护数据的索引或者主要字段用于列表显示,真正的大而全的数据还需要其他方法解决。

静态化

对于大多数场景,我们的数据在一定时间内都是不会变化的,或者说即使变化,也只是页面的一小部分会发生变化,可以将不变化的部分单独拿出来做静态化。比如京东商城的页面就是静态化的,静态化以后,数据不用每次都从缓存或者数据库中取得,然后再封装成页面,而是直接请求返回静态页面,性能无疑提升了非常大。

(编辑:东莞站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章