企业网站如何设计网页杭州模板网站
2026/3/29 7:15:24 网站建设 项目流程
企业网站如何设计网页,杭州模板网站,vps搭建wordpress个人,wordpress怎么看分类id亿集流量自己的提取 注#xff1a; 这里感觉是对需求的探讨和技术选型的分析#xff0c;但是不一定就有最推荐的具体设计#xff0c;更多的是提供思路。 这里有的东西并不具有通用性的服务设计#xff0c;所以仅讲解 基本通识#xff0c;不做具体设计。 还有这里感觉我更…亿集流量自己的提取注这里感觉是对需求的探讨和技术选型的分析但是不一定就有最推荐的具体设计更多的是提供思路。这里有的东西并不具有通用性的服务设计所以仅讲解 基本通识不做具体设计。还有这里感觉我更多在意的是技术选型而不是具体的流程图怎么做的。还有一点这里总是说高并发但是实际上用的到这个的公司的部门可能没多少比如要求是亿级别的用户但是实际上自己所在的公司可能用户还没员工多呢所以可以只是当作一种可以扩展来应对更多挑战的技术选型来使用。或许也能当作设计题的思路来使用去看书里的每章小结也不错1高并发场景一些大体骨架形成高并发系统主要有三大必要条件高性能相同硬件下性能高提升用户等待时间长体验。高可用长期稳定运行不经常出故障。可扩展可以水平扩容防止请求量突增。高并发读读多写少的情况是常见的比如说刷帖之类的。这是高并发压力主要来自读请求可以把数据库分为读库和写库。读写库分离接下来谈谈读写库分离的好处坏处用一句话总结读写分离最大的好处那就是通过牺牲“强一致性”换取系统的“极致稳定性”与“无限水平扩展能力”。可以对读库写库特化好处1资源隔离写操作会涉及到很多重量级的操作比如锁竞争需要间隙锁写的行锁之类的。写操作要写 Undo Log、Redo Log、Binlog还要刷盘。读操作要从磁盘加载数据到 Buffer Pool。如果都在一台机器上会互相抢占磁盘磁盘 IO 会成为瓶颈。数据库的内存Buffer Pool是有限的。大量的写操作会频繁置换掉内存里的热点缓存数据。读写分离后从库的内存可以专门为查询服务命中率更高。2水平扩展写库是难扩容的在传统的单主架构中写库只能靠“垂直扩容”加 CPU、加内存但总有上限。但是读库只需要复制粘贴服务器从库挂载到主库就行。3可以针对读写库分别单独特化比如说读库用mvcc完全无阻塞这里不会像读写共存时经历很长的undolog版本链因为读库不需要像读写用一个那样并发竞争许多事物都在锁。读库直接照着写库的binlog重放就可以不需要考虑并发竞争产生的版本链很短。写库的索引越少越好因为索引会影响写入性能。但是读库可以多上索引来满足更多搜索条件。这个技术选型的顾虑以下情况不考虑使用成本不足这种一般是需求也用不上要求强一致性读写占比接近需求未达到单机瓶颈mysql合理索引单机qps5000不成问题。反之读高并发且不追求实时性/需要异步之类的就直接上。读写库分离带的附加问题数据库读/写分离架构依赖数据库主从复制技术而数据库主从复制存在数据复制延 迟主从延迟因此会导致在数据复制延迟期间主从数据的不一致Slave获取不到最新 数据。针对主从延迟问题有如下三种解决方案。1同步更新太慢了异步是优点本来就是在用实时性换效率还要反过来就是本末倒置。2强制读主看到这个标题有点像juc的volait暴漏强制去主内存这里是主库读取。这个主要看业务对于实时性的需求和容忍程度。3会话分离比如某会话在数据库中执行了写操作那么在接下来极短的一段时间内此会话的读 请求暂时被强制路由到数据库Master,与“强制读主”方案中的例子很像保证每个用户 的写操作立刻对自己可见。暂时强制读主的时间可以被设定为略高于数据库完成主从数据 复制的延迟时间尽量使强制读主的时间段覆盖主从数据复制的实际延迟时间。就是有过写操作的会暂时强制读主算是分类结合。考虑本地缓存将网络请求转化为高效的内存存取逻辑。这就是本地缓存的主要用途。虽然缓存使用空间换时间可以提高数据的读取效率但是内存资源的珍贵决定了本地 缓存不可无限扩张需要在占用空间和节约时间之间进行权衡。这就要求本地缓存能自动 淘汰一些缓存的数据淘汰策略应该尽量保证淘汰不再被使用的数据保证有较高的缓存命中率。淘汰策略FIFO就淘汰最老的基本上没有可用性因为只是实现简单一点没考虑缓存数据的组有选择。LFU淘汰使用次数最少的数据有过一些选择但是还有一些缺点。比如新的热点数据次数还没上来就被淘汰了。而早期热点但现在非热点还会占据位置。LRU针对LFU的优化淘汰最近最少使用的数据是用双向链表配合哈希表使用会将最近使用的数据放在链表尾部就是按照时间排序每次淘汰头部的。但是偶发性访问冷数据放在尾巴导致把真正的热点数据淘汰或者批量访问数据造成了一批不是热点的脏数据把真正的热点搞丢是这个的缺点。这里的哈希表存的是指针不是位置所以所有操作都是O1为了删除也是O1采才用的双向链表W-TinyLFU这个自然是lru进一步的优化也是最终的方案。java的本地缓存caffeine cache也是用的这个。这个看起来就很像jvm的分代回收算法。分为两个段一个是lru段空间占比1%其余都是slru段这里是进一步划分为试用段和保护段。工作流程如下首次来的数据进入lru段lru段满的时候按照lru规则将被淘汰的数据放入slru的试用段当试用段满的时候再移入保护段当保护段满的时候再移入试用段但是要是试用段满了就按照试用频率丢弃少的多的继续流在保护段。十分甚至九分的像jvm的分代回收算法啊。再讲讲这里的哈希统计次数的方法cms:使用多种哈希方法来减少哈希冲突风险非常省空间。用准确计数来换空间主要是为了区分度这里还有时间滑动窗口集体/2.本地缓存的选择也可以搞个技术选型Caffeine(Java 缓存王)、Guava Cache 的演进版什么的留白本地缓存带来的问题本地缓存没有造成的缓存击穿。Golang语言扩展包提供的同步原语SingleFlight能很好地解决缓存击穿问题。如图2-5 所示SingleFlight可以将对同一条数据的并发请求进行合并只允许一个请求访问数据库 中的数据这个请求获取到的数据结果与其他请求共享。分布式缓存本地缓存存在着一些缺点比如内存很珍贵多个服务不能共享本地缓存内存容易丢失服务重启缓存数据就会全部丢失。所以需要分布式缓存主流的是redis所以常见的三层缓存架构是本地缓存redis分布式缓存mysql存全量数据。这就会引出各种redis的问题redis的缓存穿透,击穿,雪崩。保障mysql与redis缓存一致性。这里先留白。高并发写数据分片之分库分表数据分片是很常见的提高消费能力的手段比如地铁站的多个炸鸡。而在数据库方面的数据分片是分库分表。分库和分表是两个概念但是一般会同时进行所以就放在一起。当出现数据量每个表几亿行存不下就要分表并发量大单个库扛不住就要分库。分表的目的是提高一台服务器的数据处理能力分库是更好的利用多台服务器类似于充分利用cpu核心数。垂直拆分垂直来看是数据但是是拆分对应的就是拆字段。无论是库还是表都是对字段的拆分。可以更好的隔离核心数据与非核心数据。水平拆分同理水平拆分对应对应的就是数据可以按照范围1-100啊哈希啊一致性哈希对数据来拆分。水平拆分一般是数据量过大.一致性哈希是一个环专门为了变动产生的但是需要配合虚拟节点才能均匀的实现。普通哈希修改容量改变公式会需要变动很多而一致性哈希%的是2^32不是长度还是环形受影响的就会很少增或者删除都是顺时针找变动。再谈谈分库分表对高并发写的好处是什么就是库的数量上来了相当于售票处增加了更多的机器io写入能力增强了。数据库的扩容这里是对要扩容的库用一个从库来复制最后一人留一半实现扩容一般是对所有库扩容数量翻倍。这里看我们水平拆分库不也是扩容吗实际上这只是水平拆分带来的一个结果他还有别的许多目的。异步写写聚合考虑到增加库的成本可能比较高这里从另一个角度来看。把写操作放到消息队列里面再冲数据池中读取并执行不需要同步的等待结果返回也可用来对流量削峰填谷。写聚合这个就是多个请求合并为一个请求经典的聚合操作来节约io次数。2提高服务高可用手段本章关键词重试、熔断、限流、自适应限流、降级、强依赖、弱依赖。在微服务架构中为了解决上述种种影响服务可用性的问题笔者认为可以从如下两 个方面来考虑。◎容错性设计。要接受网络脆弱与下游服务质量不可靠的事实并在进行服务设计 时充分考虑相应故障产生时的容错方案。◎流量控制。既要对上游服务调用采取预防性策略防止打垮我们的服务也要对 下游服务有感知与保护意识当感知到下游服务的质量下滑甚至服务不可用时 及时通过自身保护下游服务。重试幂等性很经典mysql唯一约束redis全局唯一idmysql存全局唯一id的防重表插入成功才能执行操作redis全局唯一id也有两种实现1第一个来的去redis执行setnx写入请求自带的uuid全局唯一id写入成功就是第一个失败就拦截请求返回成功。2第二个是从redis获取token全局唯一id拿去接口请求redis执行删除删除成功执行没有删除成功就直接返回保障幂等。一般用第一个就行比如电商场景追求效率第二个是金融之类的用。第一个一次网络io就可以第二个要来回先拿token再去比较一共两次影响效率。但第二个比较安全一些。重试很像乐观锁的自旋注意重试是提高单次请求的成功率而且只有幂等接口才可以重试。rpc接口重试的原因逻辑错误不满足代码下游服务限流拒绝提供服务网络抖动超时重试的退避策略◎无退避策略请求失败后立即重试。◎线性退避策略每次请求失败后都等待固定的时间重试。◎随机退避策略在一个时间范围内随机选取一个时间等待重试。◎指数退避策略对一个请求连续重试时每次等待的时长都是上一次的2倍。 很像tcp网络拥塞算法的第一阶段慢启动第二阶段常数启动◎综合退避策略可以是指数退避策略与随机退避策略结合的形式各开源消息中 间件在应对消息消费失败时常使用此策略。根据接口重试的原因来选择退避策略逻辑错误不重试因为逻辑错了下游服务的问题用指数退避网络问题就立即重试在下游服务没熔断的前提下。重试带来的问题重试虽然可以提高服务质量但是也会给下游服务带来服务质量风险。假设在用户请 求量较大的晚高峰时间由于下游服务容量不足导致服务负载升高质量下降上游服务 的请求调用就会出现网络超时或网络断开的情况。这时如果上游服务决定重试请求那 么就会导致下游服务的负载继续升高服务质量继续下降最终拖垮整个服务。重试带来 的请求量放大会使下游服务的负载压力雪上加霜每个请求的重试次数越多下游服务的负载压力就越大。如果上游服务未限制每个请求的重试次数无限重试则等同于请求量被无限放大, 对下游服务的影响也会无限大。因此上游服务应该为每个请求都设置最大重试次数。在 大部分互联网公司的生产环境中一般请求失败后最多重试3次即额外重试2次。翻译重试次数过多就会占用cpu资源所以一般限制最多三次但即使这样也可能出现重试风暴。3^n取决于微服务数量重试需要谨慎进行否则它会成为洪水猛兽。重试是为了提高服务质量如果某请求 的重试不会保障服务质量那么就一定不要重试。这里总结了一些不应该重试请求的场景非关键下游服务上游服务的重试请求不再重试服务质量异常错误重试也比较宝贵所以选择具体场景不重要的就不重试。熔断和隔离熔断和隔离器不太感兴趣熔断上游服务保护下游服务不被打垮。隔离防止下游服务调用相互影响。一般使用线程池隔离或信号量隔离策略对每 个下游服务的调用做并发控制。这里就是讲各种熔断器。限流限流下游服务保护自己不被上游服务打垮。重试、熔断、资源隔离都是上游服务为了提高自身服务质量和 适当保护下游服务而采用的策略。而这里看看下游自己能做什么为了应对多个上游服务的请 求访问以防被上游服务打垮应做好的预防机制这个预防机制就是老生常谈的“限流”。可以把各种限流算法也抽象一下像是tcp的限流之类的单机限流限流算法1滑动窗口最简单的实现是通过固定时间窗口来实现的比如限制在1S内请求量不超过 100个。但是缺点是可能出现边界流量暴增2倍比如前一个窗口的最后和后一个窗口的最前凑到200。我们可以使用滑动时间窗口的方式来弥补上述缺点。滑动时间窗口把时间线以更小的 时间粒度如50ms划分为一个个槽将限流计数均摊到每个槽。一个时间窗口就是最 近时间的20个槽的总和。1.当一个请求在时间点T TT到来时限流器会锁定以T TT为终点、向前推 1 秒的这个“滑动窗口”包含当前的 20 个槽。2.限流器会把这 20 个槽里的请求数加起来得到总数S u m SumSum。3.如果S u m 100 Sum 100Sum100阈值则允许通过并在当前时间对应的那个小槽位里 1 11。4.如果S u m ≥ 100 Sum \ge 100Sum≥100则直接拒绝。这样可以防止边界暴增就是从每一秒换成看前一秒再把槽细分就可以。缺点就是这个需要遍历检查有点浪费cpu。限流算法2漏桶漏桶算法很好理解。一个漏桶承接水流并通过一个出水口匀速出 水当水流过大、漏桶已满时会导致水溢出。水流被视为进入服务器的请求出水口匀速 出水可被视为服务器处理请求的固定速率当请求过多导致漏桶满了时将开始拒绝新来的请求。漏桶算法是先进先出概念的体现可以使用队列实现漏桶。每个新来的请求都先尝试 进入漏桶如果漏桶已满则拒绝请求否则请求在漏桶中排队服务器按照固定的时 间间隔从漏桶中获取第一个请求并对其进行处理。使用漏桶算法请求可以以任意速率进 入服务器而服务器永远以固定的速率处理排队的请求。省流就是消费能力容量有限满了就进不来而且先进先出。缺点是让需求强行排队而且也无法应对徒增流量。限流算法3令牌桶主要是为了消除漏桶的缺点令牌桶算法的基本工作流程如下。(1) 每秒向令牌桶中放入r个令牌即每1/r秒新增一个令牌。(2) 令牌桶容量为们即最多存放力个令牌桶满时新放入的令牌会被丢弃。(3) 当一个请求到来时从令牌桶中获取一个令牌。如果桶中有令牌则令牌总数减 1,请求被允许执行。(4如果桶中没有可用令牌则该请求被限流。这么一看和漏桶对比他的优点就是可以把先前没用到的流量给攒起来而不是硬性限定流量。全局限流与单机限流不同全局限流旨在对一个服务的所有实例统一限流所有服务实例共用 一个限流配额这个限流配额一般由专门的限流服务器下发。当一个服务的任意一个实例 收到请求时服务实例的限流模块会先访问限流服务器查询此请求是否被允许通过而 限流服务器根据自身规则决定是否触发对此请求的限流。可以用redis实现全局限流和“在N秒内最多执行M次操 作的频控场景”的频控方案一样。使用Redis频控方案进行全局限流限流效果精准、时效性强但是由于Redis会成 为业务服务的额外单点反而影响了业务服务的稳定性所以此方案只适合请求量不大的 服务。而使用时间片统计方案注定不会有精准的限流阈值控制时效性也没有绝对保障 所以它更适合请求量大的服务对请求进行粗略筛选。时间片平时每台机器只在本地记录请求次数到了定时的时间片全部汇报给限流中心发现超了会下发降温系数让所有人在下一个时间片执行这样的操作下发降温系数超过的权重对于新来的按照降温系数丢弃。主要使用大概的限流来换更高的效率。这么看来是一个很马后炮的做法实际上一般是两层防线单机限流作为保命防线时间片大局宏观调控。实际上并不是所有的业务场景都需要进行全局限流。如果限流的目的是保护服务不 被大量请求击垮那么进行单机限流即可没有必要上升到全局限流而如果限流的目的 是对某个共享资源的全局访问控制则可以进行全局限流比如秒杀场景可以参考使用商 品的总库存作为限流阈值对用户抢购请求进行全局限流。省流先看需不需要再进行redis/时间片的技术选型。自适应限流无论是时间窗口、漏桶算法、令牌桶算法还是全局限流方案限流阈值都是人为设 置的这就意味着这些限流策略的实际效果很被动依赖限流阈值的设置是否足够合理。 为了设置合理的限流阈值在一个服务正式上线前我们一般会事先对它进行一段时间的 全链路压测再根据压测期间服务节点的各项性能指标选择服务负载接近临界值前的 QPS作为限流阈值。基于服务的压测数据得出的限流阈值看似是合理的但是服务的性能 会随着服务的不断迭代而变化。自适应限流就是看指标关注各种指标来选择是否要抛弃请求。降级策略降级保障服务核心功能的可用性具体的实施方案比较灵活。◎使用服务依赖度表示下游服务的重要程度当服务压力升高时可以切断不重要的 下游服务调用将服务资源倾斜给重要的下游服务。◎对于海量的读请求可以使用多级缓存数据或兜底数据做降级策略兜底数据可 以是静态数据也可以是来自另一个数据源的数据。◎对于海量的写请求异步写和写聚合是较为通用的降级策略在某些业务场景中 也可以丢弃写请求减小写请求量级。3唯一ID生成器前面提到了幂等性的redis全局唯一id除了这个外也有许多需要id的地方如用户ID、商品ID、内容ID等这里小看一下这个类似轮子的东西。早期互联网用户少靠着单体mysql的自增id没问题之后用户数量激增就变为了分库分表的分布式架构一个业务实体的数据备份到了多个数据库里会出现相同的自增id此时如果还使用自增id当主键会出现许多相同的id造成问题所以我们需要分布式全局唯一id。除了要保证分布式id不重复以外还需要保证以下特点空间占用小高并发和高可用可作为数据库主键。对于最后一点是什么理解呢b树是每层有序的结构所以使用自增性质的字段作为主键是一个很好的选择。非自增的话如果新数据在中间为了给新数据腾出位置B树不得不将已有的数据向后移动—如果数据页已满则会进行多次分页操作。频繁的数据移动和分页操作使得B树在磁盘上产生大量的碎片且 时间开销很大。因此官方建议尽量使用自增性质的字段作为InnoDB数据表的主键。所以id生成器也要保证自增性质的主键。占用8字节64位的long类型整数适合用作唯一 ID,因为一是long类型虽然占 用的空间较小但是可表示的ID范围却非常大二是long类型整数很容易实现递增的效 果。至此本章的议题已经明确设计一个可以生成递增的long类型唯一 ID的生成器。而这里递增也有单调递增和趋势递增一个是严格大于另一个大体趋势上就行虽然在一小段时间内数据 有乱序的情况但是从整体趋势上看数据是递增的。几种生成递增id的办法单调递增1redis用Redis INCRBY 命令在redis里维护一个全局计数变量每次根据这个拿idredis还是单线程更好的维护全局变量。而这里还有优化就是批量从redis拿id存到本地里面。2mysql专门用一个表只保留自增主键每次插入一条数据再用这个的id来作为生成的id。同样可以改为批量获取。趋势递增1时间戳时间戳是用64位来表示的系统也是64位的。这样不就意味着唯一 ID正好可以用时间戳 表示吗这种做法是不可取的原因很简单在高并发场景下同一时间有很多业务请求 到达唯一 ID生成器如果用时间戳表示唯一 ID,就会生成重复的ID。而且我们也不需要用1970作为起点可以用服务开始时的时间作为起点再减少几位来存放业务和请求的第几位也能表示好几十年左右大概69年。雪花算法就是针对时间戳的问题具体第几位怎么安排。◎ 1位符号位固定值为0,用于保证生成的long类型ID是正整数。◎ 41位存储当前时间与指定时间(可以是上线时间)的毫秒差值从指定时间开 始可运行241 : (1000 x 60 x 60 x 24 x 365) « 69年。◎ 5位用于区分不同的机房最多支持25 32个机房。◎ 5位用于区分ID生成器服务的不同实例支持25 32个实例。不过这5位与 前5位共享10位存储空间一如果是单机房环境则无须区分不同的机房可以 用10位来区分ID生成器服务的不同实例即支持1024个服务实例如果最多会 建设6个机房则区分不同的机房只需3位可以用剩下的7位来区分ID生成器 服务的不同实例。◎ 12位最后12位用于区分单个ID生成器服务实例在同一毫秒内生成的唯一 ID, 最多支持2翌4096个唯一 ID,即单个服务实例Is可支持约410万个唯一 ID生 成请求。Snowflake算法是想告诉我们需要将所考虑的高并发与分布式环境下的变量都体现 在唯一 ID上不是必须使用41位表示毫秒级时间戳、5位表示机房、5位表示服务实例、 12位表示同一毫秒内的并发请求而是应该按照实际的业务情况进行灵活调整。为了保证生成的ID的唯一性应该为ID生成器服务的不同实例分配不同的服务实例 ID ( worker ID )o这其实也是唯一 ID生成器的问题。这里存在一个时钟回拨的问题用石英晶体模拟时钟会有误差在正常情 况下每天的计时误差在Is内而在极端条件下如低温误差会变大。这种现象被称 为“时钟漂移”。2mysql基于数据库的自增主键也可以生成趋势递增的唯一 ID,且由于唯一 ID不与时间戳关 联所以不会受到时钟回拨问题的影响。分库分表架构将自增主键的自增步长与分表个数强行绑定。将基于这个思路实现的 分库分表架构应用到唯一 ID生成器服务就会生成趋势递增的唯一 ID,有效地解决了数 据库单点问题并在一定程度上提高了数据库并发吞吐量。但是以系统整体的可 扩展性较差无法对数据库进行任何扩容操作。也就是说这个方案只适合不需要扩容的 场景。趋势递增的好处如果采用从数据库中批量获取ID的方式则可以大幅提 高系统性能但是任何时刻只能有一个服务实例工作否则生成的唯一 ID将不是单调递 增的而是趋势递增的。这恰好是我们需要的效果。既然生成的唯一 ID是趋势递增的那么唯一 ID生成器服务可以有任意多个服务实例。省流只追求趋势递增的话可以采用多个实例同时生成来提高效率。美团开源方案leafLeaf是美团点评公司基础研发平台推出的一个唯一 ID生成器服务其具备高可靠性、 低延迟、全局唯一等特点目前已经被广泛应用于美团金融、美团外卖、美团酒旅等多个 部门。Leaf根据不同业务的需求分别实现了 Leaf-segment和Leaf-snowflake两种方案前者基于数据库的自增主键了批量缓存ID的思想后者基于Snowflake算法。Leaf-segment基于mysql实现的这里是单表结构且只存了一行数据字段是biz_tag区分业务方max_id最大唯一idstep下次生成多少iddesc业务信息update_time时间戳。比如在数据表中外卖业务方的biz tag为waimai_ordertag,此时max_id为10000, step 为2000,那么外卖业务方下次得到的唯一 ID号段是10001〜12000, max_id的值被更新 为12000。通过修改step字段值可以方便地控制一个业务访问数据库的频率如果step 为1,则说明每次生成唯一 ID时业务方都要访问数据库如果step为1000,则说明每用 完1000个唯一 ID时业务方才再次访问数据库。而且这里多个id生成器实例不干扰服务 A 拿走了10001~11000。服务 B 同时来进货它UPDATE之后拿到的是11001~12000。大家各发各的互不冲突也没有锁竞争。问题如果服务 A 把 1000 个号发完了再去数据库拿新的中间会有一次网络请求。万一这时候数据库卡了一下发号服务就会停顿几百毫秒。这对于高并发系统是不可接受的。解决双 Buffer服务 A 的内存里有两个桶Buffer。桶 1正在发号比如剩 50% 了。服务 A 发现桶 1 用了一半立马启动一个后台线程悄悄去数据库把下一个号段桶 2申请下来放在内存里备用。等桶 1 发完了无缝切换到桶 2完全没有网络等待时间。省流1不使用mysql自增id。用普通的表记录当前id位置2用step记录批量产生的id3可以有多个id生成器实例只保证递增趋势的好处这里是通过update行锁保留的自己版本4双缓冲防止网络波动Leaf-snowflake这个就是类似雪花算法的了上面那种的一个坏处是id会反映真实的数据订单量在对于这个敏感的业务类型不适合使用。主要看这个和传统雪花算法的区别1引入 ZooKeeper利用 ZK 的持久顺序节点。新机器一启动找 ZK 领一个号比如worker-001以后这就永远是我的号了。2针对时钟回拨的问题解决方法不一样标准雪花算法通常的做法很简单粗暴发现系统时间比上次记录的时间小直接报错抛异常拒绝服务。还要等人修好重启。而这里的解决方法因为这个有问题一般都是机器有问题防御 1查历史启动时去 ZK 查一下“我上次上报的时间是多少”。如果现在的系统时间比上次还小说明机器时间有问题禁止启动把故障拦在源头。防御 2查队友启动时去问问集群里其他机器“现在几点了”。如果我的时间跟大家平均值差太多说明我的表不准禁止启动。防御 3周期上报运行中每 3 秒上报一次时间给 ZK留下“证据”防止下次重启出问题。3依赖 ZK 分配 ID那 ZK 挂了我服务是不是也得挂Leaf-snowflake 思维本地缓存文件每次从 ZK 拿到 Worker ID 后会在本地磁盘写一个文件记录下来比如leaf.properties。容灾下次启动时如果 ZK 挂了Leaf 会读取本地文件“哦我上次用的是 5 号 ID”然后直接使用 5 号继续工作。价值这叫**“弱依赖”**。中间件挂了不影响核心业务启动。持久化保存id防止中间件挂了。4用户登录用户登录服务需要满足以下特点密码安全数据库里至少md5加密吧传递的时候也要保证安全。支持多种登陆方式手机号密码手机号验证码之类的。支持登录状态查询。密码保护使用https的ssl握手以及非对对称加密可以保证密码在传输过程中的安全但是无法保证入侵客户端和服务端的安全在那里仍然明文存储。再使用单向加密的方法(md5之类的)把密码存储在数据库里。登录态管理客户端与服务端之间的通信是基于HTTP的而HTTP是无状态的即客户端每次发 出请求时都永远无法得知上一次请求的状态数据任何请求之间都是相互隔离的。比如客 户端发起一次用户登录请求之后再发起请求时并不知晓用户已经登录更不知道自己的 请求来自哪个用户。若要真正安全且正确地识别出请求的发起用户ID,则需要使用专门的用户登录态方 案来管理其目标是可以做到认证用户用户是否已登录以及请求是否真的是此用户发 起的。1存储方案session客户端的cookie里存的是sessionid再把session存到redis里。选redis的原因所有用户都要查询session所以需要满足高性能高可用可扩展就选择使用redis存储session。具体的流程就是用户发起登录请求完成登录请求后redis创建session再下发sessionid之后就靠这个去redis里查询。因为cookie的sessionid是在客户端的有被修改的风险所以需要用加密算法计算数字签名之后验证不一样就说明cookie被修改了需要重新登陆。这个方案的优点是简单清晰易于实现也可以主动踢人统计登陆用户数量。缺点是对redis依赖很强redis如果出现网络抖动会出现服务不可用状况而且用户多了会使用很多redis资源会比较浪费redis存储资源。2计算方案令牌我们一般会将业务场景分为两种业务类型io密集型和cpi密集型。像是session就是典型的io密集型比较依赖存储系统。而这里的令牌方案是由服务端根据用户信息加密生成令牌的cpu密集大量计算的场景。令牌内部也是存用户相关数据和这些数据加密后对应的数字签名来防止被修改。令牌方案不依赖存储系统服务端通过计算就知道是否登陆过以及识别用户id。所以性能比较好。但是服务端很难管理用户比如无法踢用户下线和统计用户登录信息。虽然也可以在redis里存一个黑名单来实现主动踢人但是有点违背完全无状态了但是和session对比这样对redis的依赖已经很弱了。这个还有个个缺点就是做不到无感刷新。3长短令牌混合在客户端用寿命短的例如30min的jwt令牌再在安全的地方存加密的长令牌可以是不可逆随机字符串uuid再用redis存版本号来代替黑名单。这个就可以做到无感刷新短令牌去找长令牌延长寿命。拥有海量用户的应用非常适合采用长短令牌方案来管理用户登录态因为它结合了 Session方案和令牌方案的优势同时补齐了两者的短板。◎高性能、高可用性短令牌相当于长令牌的缓存用户请求在短令牌的有效期内 可以通过本地计算高效识别用户登录态使得真正需要长令牌访问Session数据的 请求量大大降低。◎服务端管理用户登录长令牌作为登录态的最后决策者依然可以操作和统计用 户登录态只不过降低了一些时效性二维码登录二维码是特殊的编码方式将数字信息编码成黑白相间的矩阵图案我们仅需要知道一段数据可以被编码 生成二维码图片使用手机扫描二维码图片可以将其解码回原始数据即可。1小 A 在网页端点击 “扫码登录”。2网页端展示了一个二维码并提示小 A “请打开手机 Friendly 客户端扫一扫登录”。3小 A 打开手机使用 Friendly 客户端的 “扫一扫” 功能扫描二维码。4扫码完成Friendly 客户端自动跳转到登录确认页面询问小 A 是否确认登录。5小 A 点击 “确认” 按钮登录。6网页显示登录成功小 A 在网页端登录了与客户端相同的账号。这么看就是在手机端已经登陆有用户信息时通过扫码把电脑的客户端也继承这个用户状态。二维码编码的原始 数据是一条跳转指令和一个UUID◎跳转指令用于告知客户端请跳转到登录确认页面。◎ UUID用于全局唯一标识这次扫码登录请求也可以将其理解为二维码的唯一 ID。等待小A点击“确认”按钮后携带UUID向服务端发起确 认登录请求。由于手机客户端是已登录状态所以服务端可以从确认登录请求中识别用户 ID,然后记录UUID已被此用户ID成功扫描。至此手机客户端的工作就完成了。网页端需要知晓登录是否成功。因为网页端无法感知到用户什么时候扫码 所以网页端在二维码图片展示出来后会周期性向服务端轮询此UUID的二维码是否已被 扫描、被谁扫描。服务端查询到UUID的二维码被小A扫描了于是生成与登录态相关的 SessionlD或新令牌下发给网页端。小A在网页端的后续任何请求都会携带登录态信。服务端可以使用REis存储一 个二维码是否被扫描的信息设置Key为UUID,如果二维码被某个用户扫描了则设置 Value为用户ID如果未被扫描则设置Value为0。此外一般需要为二维码设置有效 期。如果在指定的时间内(如Imin)没有完成扫码则二维码应该失效。所以也需要 为Key设置一个过期时间。5内容发布主要是帖子之类的可以类似小红书。内容发布系统并不是一个简单地进行内容创建与数据存储的系统其中有很多的业务细节与技术细节需要考虑。这里先抛出如下几个实际问题。◎ 内容的表现形式可能是短文字、长文字、图片、音频、视频也可能是这些表现形式的组合我们应该怎样合理地存储内容◎ 用户发布的内容可能涉及反动、血腥、色情等问题我们应该怎样迅速检测并屏蔽这些内容◎ 内容渠道有很多比如主页、推荐流、好友动态、搜索框等我们应该怎样让这些内容渠道得知用户发布的内容◎ 内容一般读多写少热门内容如热点新闻、明星八卦等都会直接吸引海量用户点击我们应该怎样设计系统才能避免系统因为无法应对海量用户的请求而导致内容无法被读取甚至服务宕机内容存储内容的表现形式可能是短文字、长文字、图片、 音频、视频等也可能是这些表现形式的组合我们应该怎样合理地存储内容文章主体如果使用mysql存储会占用较大的存储空间进而严重影响B树的查询效率。于是InnoDB存储引擎 选择将长文本数据单独存储到计算机磁盘的另一个区域而非真正插入数据表B树的磁 盘区域在数据表中仅保留对该磁盘区域的引用以便在读取数据时根据引用找到数据真 正的磁盘存储区域。这样一来每当读取一行完整的数据时必然至少涉及B树的磁盘 I/O和另一个文本数据的磁盘I/O,这将导致MySQL读取数据的效率明显下降且不符合 关系型数据库的真正用途。关系型数据库并不适合存储内容主体。那我们该怎么存储呢上面的innodb做的方法给我们提供了一些思路就是把文章主体的内容存放到别的地方和标题之类的在一起的是引用。这也是一种很有用的思维所以将相对格式化的内容元信息存到mysql内容主体可能是文本、图片、音频、视频等各种形式或者它们的组合所以下面还会对这个的选择做一个技术选型。这里关于内容元信息需要两张表一个是存储信息表包括创作者id和内容主体存储地址之类的一个是修改历史表这个主要是暂存还没有审核的新的内容元信息。类型典型代表存哪存什么核心优势内存 KVRedis内存小数据 (Token)快到极致磁盘 KVCassandra磁盘结构化短文本海量写入不宕机文件存储HDFS磁盘原始日志/大数据适合离线大数据分析文档数据库MongoDB磁盘JSON 报文数据结构灵活好开发对象存储S3 / OSS磁盘/云图片/视频/安装包便宜、稳定、存大文件所以决定短文本采用磁盘kv/文档数据库。长文本/别的类型的文件使用分布式文件存储/对象存储。最终选定使用分布式KV存储系统存储内容的短文本使用分布式对象存储系统 存储长文本文件、图片文件及音视频文件。音视频的特殊性如果用户上传的内容包含音视频那么一般需要进行音视频转码。这里要特别讲一下 视频转码的概念视频转码指将已经编码的视频码流转换成另一种视频码流以适应不同 的网络带宽、终端处理能力和用户需求。转码在本质上是先解码再编码的过程因此转换 前后的码流可能遵循相同的视频编码标准也可能不遵循相同的视频编码标准。转码后的 视频和原视频在内容上完全一致。转码的好处提高兼容性不同设备更多的支持。更多画质针对高画质收费。加入水印之类的保护版权。内容审核内容发布系统息息相关的一个周边系统审核中心。审核的时机几种内容审核的时机策略1任何用户发的都审核。这种是最安全的但是效率很低也很浪费资源和时间。2审核粉丝数量多的最近一段时间被举报次数多的作者发的作品没审核过但是有一定数量用户举报的内容没审核过但是突然浏览量激增的作品。下面是这样的原因审核的目的-是防止不合规的内容污染产品生态-什么体量的内容更容易造成负面影响粉丝数量多的/播放量多的什么人发布的作品更可能是不合规内容经常被举报/审核不通过通过上述几种内容审核时机策略的设计当不健康的内容有广泛传播的苗头时可及 时对其审核并对曝光量很小的内容放弃主动审核而是依赖用户举报这样一来审核 数据量相比方案一大幅度减少。就是在牺牲完全审核来提升效率。这里建议把这个临界换为可以动态修改的配置可以更加灵活的在特殊时期做好审核。怎么审核上面是审核的时机接下来该看看怎么审核。对事物的拆分因为不同的互联网公司对内容的评判有不同的审核标准审核技术的原理差异较大 且在审核逻辑中包含较多专用的业务逻辑并不具有通用性的服务设计所以本节仅讲解 基本通识不做具体设计。审核一般为分为人工和非人工。对于非人工主要是为了节约成本对于文本一般是提取再进行敏感词匹配图片会采用图像处理技术来判断音频会转为文字视频则选取关键帧来审核。但是我们都知道不能完全信任非人工所以可以加上置信度如果置信高的话就采用低的话就再交给人工审核。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询