为什么要有微服务?
微服务提高开发效能,避免业务的重复理解,代码重复开发,增加开发效能和代码复用性。
在实际的工作中许多不同的业务有着共同的功能需求,如果我们每遇到一次这种需求就重新去理解构建一次的话会花费大量的时间。但是如果我们把这些共同的需求变为一个个小的模块,在需要使用对应功能时直接去调用这些模块能大大节省时间。避免了业务重复理解,代码重复开发,增加开发效能和代码复用性。
微服务的数量很多,有着几万到几十万的微服务。
微服务的七大模块
- 中央管理平台
- 生产者
- 消费者
- 权限管理
- 流量管理
- 自定义传输协议
- 序列化与反序列化
微服务概述
微服务中有提供服务的生产者,也存在使用服务的消费者,而存在着一个中央管理平台去管理这些生产者和消费者。一个微服务既可以是生产者也可以是消费者。
生产者要先进行注册,包含名字,功能,所属部门,接口有哪些,接口说明,联系人,生产者ip地址等信息。
消费者也要先进行注册:名字,目的,所属部门,联系人,IP地址等信息。消费者可以调用多个生产者,消费者想要调用生产者要先申请。申请包括:调用原因,所属业务,所属部门,联系人,调用那些接口,某个接口每分钟调用的上限次数等信息。
中央管理平台要进行权限控制(消费者可以调用生产者的哪些接口)和流量控制(这里的流量是指访问量)。服务发现,服务治理。当某些服务的服务器出现问题了,中央管理平台也要及时的察觉出来。所以这些服务器socket(包含生产者和消费者)每隔几秒就向管理平台发送一次心跳(轮询),证明自己还活着。如果管理平台没有收到某个服务器的心跳,那么就会报出异常,向对应管理者发送信息。
一旦消费者的对某个生产者发送请求失败就要将请求分配到其他服务器上去。如果生产者新增了服务器,要让消费者也知道新增服务器的存在,让请求也能打到这些服务器上。
内网为了传输更快,要重新规定一个协议,自己研发一套。不能使用原有的http协议。
生产者
生产者注册后,会生成一个唯一标识。生产者程序,需要引入微服务相关的jar包,在一个固定的文件夹中会生成一个此服务对应的一个秘钥,那么当程序启动时,jar包就会把这个秘钥发送到中央管理平台,就能够找到对应的注册的生产者,还会把主机ip等信息也上传到中央管理平台对应的生产者,每秒钟服务器会向中央管理平台每隔几秒发送一次心跳,来证明服务器运行正常,如果中央管理平台没有收到心跳,那么就会标记异常。
在生产者压力较大时,生产者会新增服务器,通过新增生产者服务器的心跳,就能够将自己的信息通知到中央管理平台。
生产者的实现原理类似于Tomcat+springboot
消费者
消费者和生产者一样,也会需要注册,生成一个id,消费者服务器也有对应的秘钥,这样就无需手动去统计,消费者有哪些服务器了。
生产者会拥有若干个接口,消费者在申请的时候可能并不会申请全部的接口,每个申请的接口,都需要提交调用次数等信息。
微服务及其注重性能,消费者在首次调用的时候需要向中央管理平台询问,知道生产者服务器有哪些ip,然后缓存到消费者服务器本地,下次再调用就不需要再经过中央管理平台了,而是直接访问生产者服务器。
在访问的时候需要判定消费者对生产者的接口有没有访问权限,如果消费者想要越界调用某些没有权限的接口,需要消费者自己去拦截,由消费者的jar包去实现拦截。
消费者对生产者的访问权限存储在消费者的本地中,由于消费者申请接口的数量可能变化,所以每隔几分钟消费者会去中央管理平台去同步一下自己的访问权限,更新到本地。
当生产者新增了服务器后,消费者通过分钟级的轮询中央管理平台也能够发现这些新增的服务器并使用。
怎样解决生产者崩溃问题
当一个生产者者服务器出现故障后,中央管理平台有5-6次没有收到某台生产者服务器的心跳时,才能判定该服务器出故障了,这会导致一个较长的延迟。所以如果这期间会有许多的请求过来,这时如果一个消费者请求这个服务器失败了,会再try catch一次,如果还请求失败,就会更换一个服务器进行请求。并将该故障消费者服务器上报给中央管理平台,中央管理平台接到消费者对生产者的故障报告后会立刻查询有哪些消费者正在调用该台故障的生产者服务器,并且立刻向他们更新消息,告诉他们这台服务器故障了。这样的处理是毫秒级别的。
如果一共有三台消费者服务器,而这三台消费者对生产者总访问量限制为每分钟一千次,该如何进行流量控制?
1.方案一:在众多消费者服务器中,会选择一台服务器负责进行访问次数统计,到了每分钟允许访问的总次数吧就告诉大家不要访问了。这种方法,统计不精确,有延迟。
2.方案二:把这些任务去平均分给这三台服务器,一旦某个消费者服务器的请求量达到了1000,就阻止该消费者服务器继续访问。
ps:3000的访问要求并不一定要非常精确,超过几十次访问是没有影响的。
自定义传输协议
如果使用http协议,那么任意一个项目都可以作为生产者,像servlet,spring,springboot都可以,只需要引入相关jar包即可。但是为了内部传输速率的加快,通常使用自定义协议,那么这时servlet,spring,springboot就都不可以了,所以就需要架构师自己写一套类tomcat的东西,但是和tomact的区别是,tomcat识别http协议,自己写的识别自定义协议。
http协议在外网,环境比较复杂。所以规定了许多字段。但是在内网使用的时候,通常会基于http协议/tcp协议进行缩减。自定义协议定义了每个字段的范围,如何发送,怎样解析。