近段时间离职,跟同事们讲解我之前所做的微服务相关产品,对于同事们提出的问题,做了如下整理出来,加上自己的理解,分享出来跟大家一起探讨下:
问题预览
- 我为什么要换微服务?能给我带来什么好处?
- 从交互上来看,单体应用在处理业务实体之间的关系,直接由框架搞定,如java的hibernate等,而使用微服务,还要去花时间去重新整理甚至重构业务结构.
- 微服务测试起来比较麻烦:首先微服务根据不同的业务实体划分资源服务,那么也许有些业务的操作,会涉及多个微服务,那么测试微服务的话,就需要将所有的相关服务都启动完成,才可以进行测试。
- 微服务一般对外是restful服务,为了保证安全性,开销也是比较大的:一方面服务内部可能每次访问都需要安全检查,会降低效率;另一方面内部访问开启https,在证书部署维护方面也会增加压力
- 一般情况下,很多服务都存在类似session等数据存储在内存中,而这些session只在同一WebServer中存在,一般无法进行多实例共享(当然也有共享的方案,但是需要相对复杂的集群设计),该如何解决这些数据的问题呢?
- 接着上个问题,微服务的使用场景中,基本都需要实现单个服务多个实例的场景,以实现高可用,那么问题来了,我对单个服务运行了10个实例,那么该如何知道服务该向哪个服务发起访问呢?
- 接着上个问题,当我运行10个WebServer的时候,在主机上需要使用10个端口进行对应,而服务多了以后,对于端口的消耗和管理也是个比较大的麻烦
- 接着上个问题,一般的应用,我们可以使用haproxy来做代理,那么就需要每增加或者修改一次实例,就需要修改haproxy的配置,管理上的消耗也会成为比较大的麻烦,并且还有可能出错
- 对于众多的微服务实例,服务较多的至少可以达到数百个甚至数千个,监控和管理上,也将比较大的挑战
- 上面提到的很多软件,都是比较零散的软件堆叠出来的服务,有没有比较好的成套的解决方案?
问题及自己的理解
1. 我为什么要换微服务?能给我带来什么好处?
-
可以解决复杂性的问题,在功能不变的情况下,分解为多个相互协作的微服务,通过rest API定义边界,这样极大易于开发、理解和维护。
-
微服务架构是的每个服务可以由专门的开发团队或者个人开发者进行开发,开发者可以自由选择技术,不必受制于规定的技术和框架,只要API服务协议好交互方式即可(如restful)。这样即使重新技术过时的微服务模块儿或者重写以前的代码,也不是很困难。
-
微服务架构模式使得每个微服务独立部署,且每个服务独立扩展,开发者不再需要协调其它服务部署对本服务的影响。微服务架构模式使得持续化部署成为可能。
2. 从交互上来看,单体应用在处理业务实体之间的关系,直接由框架搞定,如java的hibernate等,而使用微服务,还要去花时间去重新整理甚至重构业务结构.
首先,在使用框架的同时,也已经受制于框架,甚至是开发语言的选择,单体应用下,看似方便,可是业务实体之间的关系太过于固化,当有一个业务实体需要改变,则整个应用相当于发布了一个新的版本。这种情况对于不care更新停止程序的客户来说是无所谓,可是对于服务更新停止程序敏感性比较强甚至不允许停止程序的公司来说,无疑是个灾难。所以使用微服务不是必须的,而是在适当的实际,架构适应应用场景的一种改变。
3. 微服务测试起来比较麻烦:首先微服务根据不同的业务实体划分资源服务,那么也许有些业务的操作,会涉及多个微服务,那么测试微服务的话,就需要将所有的相关服务都启动完成,才可以进行测试。
微服务测试起来麻烦是没有任何疑问的,不过微服务大多采用restful服务,这为微服务的测试提供了相对的便利性(测试restful接口的工具还是挺多的)。对于微服务带来的便利性,增加这点压力还是可以容忍的。
4. 微服务一般对外是restful服务,为了保证安全性,开销也是比较大的:一方面服务内部可能每次访问都需要安全检查,会降低效率;另一方面内部访问开启https,在证书部署维护方面也会增加压力
首先,一般微服务外部都是需要有API GateWay的,由API GateWay来保证外部访问的安全性,而内部访问,可以省去https和安全检查,仅保留必要的用户信息即可。
5. 一般情况下,很多服务都存在类似session等数据存储在内存中,而这些session只在同一WebServer中存在,一般无法进行多实例共享(当然也有共享的方案,但是需要相对复杂的集群设计),该如何解决这些数据的问题呢?
一般情况下,对于绝大部分有状态服务,在设计之初,就会考虑有状态服务的状态转移等工作,假设我们有服务存在session,那么这些session信息,可以转嫁存储在一套redis集群中,这样子就可以多个实例都访问redis,相当于状态由redis进行处理了。
6. 接着上个问题,微服务的使用场景中,基本都需要实现单个服务多个实例的场景,以实现高可用,那么问题来了,我对单个服务运行了10个实例,那么该如何知道服务该向哪个服务发起访问呢?
一般情况下,我们可以使用haproxy之类的服务,将当期服务的所有实例进行代理,可以先对单个服务单点访问,其他服务做备份,又可以使用haproxy的负载均衡,使请求平均分发到各个服务中
7. 接着上个问题,当我运行10个WebServer的时候,在主机上需要使用10个端口进行对应,而服务多了以后,对于端口的消耗和管理也是个比较大的麻烦
可以使用docker来解决,在docker的使用中,一个服务对应一个镜像,而基于一个镜像可以启动多个容器,而每个容器都可以使用统一的内部端口,不同的容器名称,我们使用的haproxy也在docker中运行,通过docker内部网络访问各个服务,这样就解决了端口问题。
8. 接着上个问题,一般的应用,我们可以使用haproxy来做代理,那么就需要每增加或者修改一次实例,就需要修改haproxy的配置,管理上的消耗也会成为比较大的麻烦,并且还有可能出错
对于这个问题,也有解决方案:首先我们可以去尝试使用如下一套解决方案“docker-swarm-consul-haproxy”,Swarm是一个用于创建Docker主机(运行Docker守护进程的服务器)集群的工具,consul用来服务发现及配置中心,haproxy则用来进行代理服务
9. 对于众多的微服务实例,服务较多的至少可以达到数百个甚至数千个,监控和管理上,也将比较大的挑战
无论是做以往的单体应用、SOA还是微服务,服务监控和管理都是必不可少的,对于监控,目前有比较好的容器监控开源程序,如:Prometheus、 cAdvisor等;管理方案可以使用简单的shipyard,复杂的可以使用kubernetes的
10. 上面提到的很多软件,都是比较零散的软件堆叠出来的服务,有没有比较好的成套的解决方案?
整体的解决方案是有的,就是个人感觉略重(我个人搭建的一些服务,没有用kubernetes,而是使用了非常简单compose+swarm)。这个方案就是使用kubernetes(基于Docker),下面可以简单描述下我这边是怎么使用kubernetes来实现微服务的:
- 首选我的微服务程序都是无状态的或者经过状态转移过的
- 对于服务发现,以往我们用consul,这里我没有去做服务发现和服务注册,而是使用kubernetes的ReplicationController来保证我的微服务实例数量(系统会自动维护)
- 对外的代理以前用haproxy,而现在使用kubernetes的service来替代,kubernetes自动处理各个微服务实例的负载及请求的分发,我们只需要保证业务稳定即可。
by 刘迎光@萤火虫工作室
OpenBI交流群:495266201
MicroService 微服务交流群:217722918
mail: liuyg#liuyingguang.cn
博主首页(==防止爬虫==):http://blog.liuyingguang.cn
网友评论