微服务和服务处理

微服务和服务处理

介绍

​ 随着需求的变化,用户、模块越来越多。

​ 我们从单一服务转变到微服务

​ 对服务、数据的处理,也多出了很多种不同的方式,

​ 最后只为了保障服务的性能和稳定性。

​ 主要简单的介绍一些微服务的常识和我们运用保障服务的哪些方案。

目录

​ 一:微服务与单体

​ 二:网关层

​ 三:分布式锁、事物和多库DB:

​ 四:分布式的一些小应用与技巧:

​ 五:缓存

​ 六:负载

​ 七:限流、服务降级、服务熔断

微服务与单体

微服务
  1.松耦合,开发阶段和部署阶段都是独立的,这样一个服务出现问题,不会影响整个应用。
  2.容易支持不同的语言进行开同一应用的开发。
  3.理论上,每个微服务都很小,这样使代码更容易理解,使开发人员更容易聚焦、专注,只需要关注自己的服务以及工作业务.
  4.部署灵活,因为是分布式,所以一个服务不大的情况下,是可以快速启动好的,不会发生单一服务构建时间长的事故。
  5.高并发:可以更好的承受并发,因为模块是分散式的。
  6.有效的利用资源,一台服务一个机器,很浪费,微服务使用容器化部署,一个服务,一个进程,更好的利用资源。分配机器

单体
  1. 开发简单直接,集中式管理, 基本不会重复开发
  2.功能都在本地,没有分布式的管理开销和调用开销。
  3.重点是比微服务:业务实现上和部署维护上,要简便了很多,不会搞得那么复杂.

网关层

api-gateway
   我们处理的简单,目前是直接使用了一套api-gateway来做的转发,前端会走http请求,进入
   到api-gateway,从而在转发到我们内部的grpc请求,模版是proto定义的,只要定义了
   proto,api-gateway就能自动生成对应的http,提供前端请求不过我们的权限认证,并
   没有放在api-gateway里,而是每个服务请求过滤那一层,就会调用grpc进行权限角色
   的认证.
权限认证:
   每个服务在过滤层,会进行调用grpc来判断是否有权限,之前在做单一服务或者是拆分服务,
   做了一些简单的分布式操作,也只是在过滤写好代码,直接查询db在进行
   判断看是否有权限,其实这样非常不好,因为权限业务有
   稍微的变动,可能就会引发其他服务的变动,而且也没有统一性,有些同学就会觉得那为了统
 	 一,直接写个包,放到gitlab上,在引用到项目不就好了,那肯定是不行的,且不说版本
   跟新,按照微服务一个服务一个db的操作(这样使开发人员只需要关注自己的业务,管理属于 
 	 自己服务的架构),就已经不太具备了,
当然,这里不是说一定要一对一的关系,只是提倡这样。

分布式锁、事物和多库DB:

分布式锁:
		主要是利用redis setnx来实现的,因为是原子性的原因,所以不用考虑在查询之前发生了两次改变怎么办。
分布式事务:
    问题:当需要经历不同的服务来做数据改变时,而且数据源也是不同的DB,那么事物怎么做?
    我之前做的分布式事务是按照任务的方式,来记录已经成功到哪一步了,每一步也有详细的记录.
    当这个事物最后一步,或者是中间一步失败时,会有个补偿机制,根据一个频率再次执行几次失败的逻辑,
    如果最后还是失败,那么就有两种方式,要么直接把之前的回滚,要么就是等待工作人员来看失败的详细日志,来进行修复.
多库DB:
    有的时候,我们有很多的库,包括mysql里,可能也有很多的数据源,但是我们需要连表查询咋办。
    我们使用的是presto,这个是基于内存计算的,他会统计你需要用到的数据做个整合,然后在允许你用sql来进行连
    表查询,因为它是基于内存,所以速度非常的快,只不过耗内存嘛,我们也是用的阿里云上的,所以也相当
    的烧钱,当然前提并不是所有数据,而是通过你的sql,来晒选出你需要的数据.
    如果是超大数据量,建议使用hive

分布式的一些小应用与技巧

封装包上传到公网然后在引用:
    就上面说的,直接写个包,放到gitlab上,在引用到项目里,这里就具备统一性,一些公用的函数就可以这样使用.
定时任务:
    想起这个就很有意思,我呆过的几家公司,可能也是之前刚开始工作技术不够,用了很多很low的办法.
    因为是分布式的,所以一个服务的定时任务,是会同时执行多次,这样情况很多业务是不允许的,那就需要处理
      第一种:定时任务不写到服务里,所有定时任务,有专门的一个服务,然后进行执行.
      需要把全部的业务操作、db操作写到一起很不好、而且服务负载也不好,因为要是同一时间执行的量大,这样处理
      起来就会很麻烦
      第二种:服务把定时任务变成api,然后通过一个专门的服务定时调用api.
          容易进行负载,但是需要专门写个接口调用的服务,而且这样的话其实是不够准时的.
      第三种:利用第三方工具,来校验哪个服务已经在执行定时任务,哪个不该执行.
          负载可行,就是需要借助第三方工具.大多还需要自己搭建.
      第四种:消息队列,同一分组、主题下只有一个tag能消费到。
          负载可行,也简单.
      emmm,没错,这四种都是我使用过的,消息队列是实现起来又简单又好用,赞.
串行化:	
    前端出现的这种情况比较少,由于转变成微服务,那么服务之间的通信就多了很多,比如一个接口需要请求另外服务
    的收获信息,
    商品详细信息,成本信息,这三个信息分别是在三个不同的服务才能取到,这样就需要先请求收获信息在请求
    商品详细信息,以此内推,就会有一个等待的过程,其实这些信息并不是完全关联的,可以一次性查完,
    所以同时请求三个接口就好了。
统一化:
		统一模版,统一生成初始架构,尽量除了和本服务业务相关的代码,其他代码,都统一好,或者封装好上传,进行引用.
数据组合:
    接口的数据组合,最好交给后端,尽量让客户端,做少量的工作,数据的组装聚合,数据量不是很大的情况下,
    没有特别麻烦的处理,其实不会造成什么压力,反而这样做会使整个架构更清晰,不会导致稍微一个接口变动,就使得
    前端也需要变.
    还有一种情况,就是有些特殊的接口,就是计算量大,并发性高,这时候咋办,自己的服务器肯定是吃不消,
    那一般这样的话,就直接交给
		客户端处理了,就想游戏行业,其实很多数据处理都是由用户的手机、电脑来处理的,这样就能降低公司服务器的压力.
DB连接池
    这个程序员应该都比较熟,最基本的概括一下.
    超连接时、最大连接数、最小连接数.
    其实最初以前很多项目都是没有用连接池的,都是直接open打开单个数据库连接,然后在操作DB。
    这样做很消耗资源,因为每执行一条sql,就需要认证、重新建立连接、tcp过程、释放连接。(当
    然我没有这么干过)
    所以服务专门弄了一套连接池管理,就是用来管理DB的连接的。(很多第三方包都写好了)
    简单就说一下,最大连接数和最小连接数就好了
    最小连接数是该连接池最初始,以及最少应该建立好多少个连接.
    最大连接就连接池允许出现的最大连接数量.
    tx会占用连接,所以记得最后一定要提交或回滚,否则它一直占用着连接.
    当本地开发时,程序启动过慢,也可以降低最小连接数,这样初始化的时候,就不用初始化那么多连接数了。
    线上预估好平均需要活跃的DB连接数,在进行最小连接数配置就好
    还有一个之前公司遇到的一个问题,就是当某一刻,并发量请求sql需要的连接数量比最小连接数多很多时,服务和数据库
    之间就需要立马建立很多的连接,其实在那一刻是来不及的,所以这个时候只需要加大最低连接数,让服务初始化的时候,
    准备足够的连接来响应就好了。

缓存

我们没弄多重缓存,可能是用户的并发量还达不到需要我们用几层缓存的程度。
我们就两种方式:第一种普通的redis就省略了。
第二种:自己启动一个服务当作缓存进行存储,我记得是之前好像有个需求需要实现树状图结构,redis肯定实现不了然后就专门
启动了一个服务实现,我反正最常用的就是临时缓存,先把数据库一小块数据缓存到本地服务,判断条件是接口是不是常用到此块数据,是的话,再根据跟新的频率,来确认是否添加缓存,这样的好处是,快,减少db压力,坏处是:占用一部分内存,跟新需要维护.
运用场景:读超多,写超少。

负载

一开始只有http请求,用的是nginx和阿里云付费的负载,进行服务分发请求.
后面来了grpc,长连接,流式的请求,自己就弄了一套基于etcd的负载
本来以为etcd负载这个技术点以前写过文章的,想直接拷贝链接进来的,结果没有......那就在粗略的写下大概.
负载是在客户端做的,服务端会有注册,心跳使用的是etcd过期机制。
客户端首先会根据etcd获取还有哪些服务在线,然后自己写了两套随机和平均调用,进行请求的发送.
服务端启动时,会给etcd注册服务信息,然后每隔一段时间,会告诉etcd自己还存在,并设置过期时间.
当服务不可以用时,服务在etcd上的信息过几秒(自己设置),就会销毁,就实现了心跳的过程.
emmm,虽然有点low,但当时还挺有用。
好一点的话其实中间有一层服务来专门做服务发现,而不是由客户端来做。
后面就是用k8s来实现整体的负载了。

限流、服务降级、服务熔断

限流
	记得几个最常见的:
    1.时间段访问量,比如一个小时之类不允许超过1000访问量.否则直接抛出请求.
    2.并发量,也就是请求没有结束之前,一共正在执行多少请求,超过1000,则直接抛出请求.
    3.令牌桶算法:
    就是有桶有令牌,然后生成的一个规则
    桶子:用来存放所有请求,在丢给令牌执行.
    令牌:一个请求对应一个令牌,只有拥有令牌的请求,才可以执行.
             可以设置最高能有多少令牌
             令牌恢复速度:当n个令牌里的请求结束后,不是立马恢复,而是通过一个恢复速度逐渐恢复,再给请求执行.
     规则:
       所有进来,包括后续进来的请求都放在桶里,根据现有的令牌来执行请求,当请求结束后,在按照速度比来恢复
       令牌的使用权
		4.分布式限流.
      就是多个服务,如何一起统计限流,总体的核心,就是就是计数然后限制,一般都是直接使用redis做存储,
      然后计数,在使用
      对应的算法。
服务降级
    当时做一个游戏行业的时候,就是手动,虽然很low,但是还是有点用,就是某些不重要的业务模块,有点吃性能,
    或者是不可用,直接通过
    配置文件使其不执行,直接抛出维护提示,只让核心业务执行.
    当然也可以通过检测警等一系列方式进行自动降级.
    我们之前使用的警报就是普罗米修斯,当然我没用这个做,一般情况下可以自己检测一下本服务器的内存,
    cpu使用率,网络等等,等达到了
           自己预期的最高值,就可以进行降级,保证核心业务没有问题,让一些无关紧要的业务可以先暂缓,
           过段时间在恢复。
服务熔断
           个人经历,我们项目当中最容易出现这种情况,就是DB操作,因为关于压力测试,其实我们
           服务器完全承受得住,主要是mysql,当到达了n亿,tb级别在往上走,并发在高点,sql在麻烦点,
           那就不好意思,DB,就容易出现问题,这个时候它往往也没有直接挂掉,只是它不能及时响应客户
    			 端的请求,当服务连接数据库,sql超时设置的是10秒,这种情况就会出现,每次访问这个db时,
    			 此请求都要等待10秒,这样并发上来了,整个服务
    			 n个请求都会陷入等待,从而导致更多的服务挂掉.
           可以自己设置一个阈值,当多久请求一个接口或者db连续返回了n次超时或失败后,
           直接不进行调用,或者多久不进行调用.

好,结束了,想不到别的了,有疑惑的或者是觉的哪儿可以改善得更好都可以私信交流 —end

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值