原文地址:https://mp.weixin.qq.com/s/QO1QDQWnjHZp8EvGDrxZvw

这是专题的第二篇文章,看看如何搭建一个简单模式的微服务架构

记得好久之前看到一个大牛说过:如果单体架构都搞不好,就别搞微服务架构。乍一看,这句很有道理,后来发现这句话是不太对的,因为微服务架构的目的就是为了降低系统的复杂性,所以 微服务架构应该比单体架构更简单、更好实践才对

这篇文章,我们就分享一下如何搭建一个 简单模式 的微服务架构。

什么是微服务架构的简单模式?

相对于大型互联网平台动辄几万并发的访问量,或者每天多次的在线版本发布,绝大多数企业和项目并没有这样的需求。他们关注的是如何更好地提高开发效率,如何更快地实现新需求,如何更便利地运维,等等。

微服务架构的简单模式就是可以满足以上需求的软件架构方案。

相对于“完美”的微服务架构方案,微服务架构简单模式可以暂且不用关注保障数据一致性的分布式事务技术、方便程序包在环境间(开发、测试、生产)迁移的配置中心组件、监控 API 调用情况的调用链组件、避免系统超载的断路器组件、方便 API 管理和测试的 API 文档框架、Zookeeper、Redis,以及各种 MQ。只需要关注常常谈到的 注册中心服务发现负载均衡服务网关 即可。

如何将微服务架构的简单模式落地?

落地微服务架构,重点就是发扬优点,克服缺点。如前篇文章《Re: 从 0 开始的微服务架构:(一)重识微服务架构》的对比所示,相对于单体架构,微服务架构最大的缺点是 上手难运维难

下面我们就来看看如何从这两个方面入手,将微服务架构的简单模式落地。

上手难

相对于传统的单体架构,微服务架构一下子引入了太多的概念,让新手有点无可适从。所以,我们更要去芜存菁,理清楚哪些是自身需要的,哪些只是江湖上的传说。下面就来看看哪些组件是开发一个微服务架构的系统所必需的。

首先说一下,使用微服务简单模式进行开发的四个步骤:

第一步:沿用组织中现有的技术体系开发单一职责的微服务。

第二步:服务提供方将地址信息注册到注册中心,调用方将服务地址从注册中心拉下来。

第三步:通过门户后端(服务网关)将微服务 API 暴露给门户和移动 APP。

第四步:将管理端模块集成到统一的操作界面上。

为了实现以上 4 点,相对应的就是下面必需掌握的基础技术(必需的组件)。

  • 注册中心、服务发现、负载均衡:对应上边第一步与第二步

  • 服务网关:对应上边第三步

  • 管理端集成框架:对应上边第四步

注册中心、服务发现、负载均衡

和单体架构不同,微服务架构是由一系列职责单一的细粒度服务构成的 分布式网状结构,服务之间通过轻量机制进行通信,这时候必然引入一个 服务注册发现 问题,也就是说服务提供方要将自己的服务地址注册到某个地方(服务注册中心, Service Registry Center),服务的调用方可以从服务注册中心找到需要调用的服务的地址(服务发现,Service Discovery)。同时,服务提供方一般以集群方式提供服务,也就引入了 负载均衡 的需求。

根据负载均衡(Load Balancer,简称 LB)所在位置的不同,目前主要的服务注册、发现和负载均衡方案有三种:

集中式 LB 方案

第一种是集中式 LB 方案,在服务消费者和服务提供者之间有一个独立的 LB,LB 通常是专门的硬件设备如 F5,或者基于软件如 LVS,HAproxy 等实现。

服务调用者调用服务时,向 LB 发起请求,LB 再根据一定的策略(比如轮询、随机、最小响应时间、最小并发数等等)将请求路由到指定的服务。这个方案的最大问题是:调用者和提供者之间增加了一跳,LB 也最有可能成为整个系统的瓶颈

进程内 LB 方案

第二种是进程内 LB 方案,针对集中式 LB 的不足,进程内 LB 方案将 LB 的功能以库的形式集成到服务消费方进程里头,该方案也被称为软负载 (Soft Load Balancing) 或者客户端负载方案。

其原理是:服务提供者将自身的地址发送到服务注册中心,同时定时发送心跳给注册中心,注册中心按心跳情况判断是否将此节点从注册表中摘除。服务提供者调用服务时,先从注册中心拉取服务注册信息,然后根据一定的策略去调用服务节点。

这种情况下,即使注册中心宕机,调用方也可以根据内存中已经拉到的服务地址将请求路由到正确的服务上去。这个方案的最大问题是:服务调用者可能需要集成注册中心的客户端,即将来注册中心服务端升级,可能会需要升级注册中心客户端

主机独立 LB 进程方案

第三种是主机独立 LB 进程方案,该方案是针对第二种方案的不足而提出的一种折中方案,原理和第二种方案基本类似,不同之处是,他将 LB 和服务发现功能从进程内移出来,变成主机上的一个独立进程,主机上的一个或者多个服务要访问目标服务时,他们都通过同一主机上的独立 LB 进程做服务发现和负载均衡。该方案的典型案例是 Airbnb 的 SmartStack 服务发现框架。这个方案的最大问题是:部署和运维比较麻烦

以上三点摘自杨波先生的《实施微服务,我们需要哪些基础框架?

http://www.infoq.com/cn/articles/basis-frameworkto-implement-micro-service#anch130564 ,

并作了部分补充,如果希望查看这三个方案的更详细说明,推荐读一读杨波先生的文章。

当下,随着 Netflix 的微服务方案和 Spring Cloud 的兴起与成熟,第二个方案 成为我们的首选。我们推荐使用 Eureka 做服务注册中心,Ribbon 做客户端服务发现和负载均衡

这个选择的最大好处是 简单 + 实用 + 可控,不用引入额外的 Zookeeper、Etcd 做注册中心,部署和运维也都比较简单。从代码上来说,使用起来也非常简单。

只是,需要注意的是,这种方案一般是用来做 局域网内 的负载均衡,如果要为开放到互联网的服务做负载均衡,可以使用 Nginx Upstream 来做。

下面是 Eureka 最重要的几个参数配置,从这些参数也可以大概看看 Eureka 是如何工作的。

由于 Eureka 的注册及过期机制,服务从启动到完全可用需要近 2 分钟的时间,所以,为了提高开发及测试环境中的发版速度,我们改了以下几个参数。生产时,一定要改回去。

Eureka 注册中心的界面如下:

详细信息可参考

https://github.com/Netflix/eureka

https://github.com/Netflix/ribbon。

服务网关

通常,一个大系统里会有很多职责单一的微服务,如果门户系统或移动 APP 来调用这些微服务的 API 时,至少要做好两件事:

  • 由统一的入口来调用微服务的 API

  • API 鉴权

这就需要一个 服务网关。2015 年,我们使用 Rest Template + Ribbon 做了一个简单的 API 网关。原理就是当 API 网关接到请求 /service1/api1.do 时,将请求转发到 service1 对应的微服务的 api1 接口。

后来,发现我们实现的功能,Spring Cloud Zuul 都有比较好的实现,也就切换到 Zuul 上面去了。Zuul 是 Netflix 基于 Java 开发的服务端 API 网关和负载均衡器。

除此之外,Zuul 还可以对过滤器进行动态的加载、编译、运行。最令人吃惊的是,Zuul 的转发性能据说和 Nginx 差不多。详细信息可参考https://github.com/Netflix/zuul。

总的来说,一般情况下,API 网关(可以称为门户后端)用来进行反向代理、权限认证、数据剪裁、数据聚合等。

管理端集成框架

掌握注册中心、服务发现、负载均衡和服务网关技术后,微服务已经可以为门户系统和移动 APP 提供可靠服务。但是,给后台运营人员使用的管理端是怎么实现的呢?

由于后端运营系统的压力不大,我们可以通过 CAS 和 UPMS(UPMS 是我们团队研发的契合微服务架构的用户及权限管理系统,我们将分享到青柳云官网,欢迎关注)将单独开发的微服务整合起来。

三步集成一个微服务的基本过程就是:

  1. 在微服务中引入基于 Spring Boot 的 security starter,starter 里包含了系统的顶端 Banner 和左侧菜单。

  2. 将微服务的访问地址注册到 UPMS 中,这个地址作为此微服务的入口菜单(一级菜单)。

  3. 在 UPMS 中配置微服务的功能菜单及角色权限信息。

用户从浏览器打开一个微服务的时候,security starter 会调用 UPMS 的 API 拉取所有的微服务清单(一级菜单)和当前微服务的功能清单(二级菜单),并将当前微服务的页面在内容区展现给用户。

应用架构图:

UPMS 截图,橙色部分由 UPMS 框架提供,红色框为微服务的页面:

UPMS 通过“模块”功能接入新的微服务:

所以,到最后,一个简单模式的基于微服务架构的系统就可以长成这样:

至此,基本的微服务架构已经搭建起来。下面来聊聊怎么解决微服务运维的问题。

运维难

微服务架构的运维问题,主要是相对于单体架构来说的。因为实施微服务架构后,整个系统的模块一下子比原来多了很多,模块变多后,部署和维护的工作量都会变大。所以,解决运维难的问题,可以先从 自动化 的角度来解决。

更进一步,如果希望更好地发挥微服务架构的优势,规避缺点,则建议准备一个可靠的基础设施,包含自动构建、自动部署、日志中心、健康检查、性能监控等功能。

否则,很有可能会因为微服务架构的缺点导致我们的团队丧失对微服务架构的信心,从而回到单体架构的老路上去。工欲善其事,必先利其器,这一点真的很重要

持续集成

单体应用被微服务化后,很有可能从原来的一个程序包分成了 10 个、20 个甚至更多的程序包。那么,我们首先遇到的麻烦就是部署工作直接扩大了 10 - 20 倍。这时,持续集成的方法和工具就成了实施微服务架构的前提条件。我们在实践过程中,利用基于 Docker 的容器服务平台自动部署整个系统的微服务。其过程如下图:

如果没有微服务支撑平台,也可以通过 Shell 脚本的形式来调用 Jenkins API 和 Docker API。

主要过程是:

  1. 调用 Jenkins 命令从代码仓库拉取代码,并打包代码。

  2. 调用 Docker /build 和 /images/push 命令构建镜像,并将镜像推送到私有镜像仓库中。

  3. 调用 Docker /containers/create 和 /containers/start 命令创建并启动容器。

配置中心

在开发 / 测试环境上,程序包已经被打包成 Docker 镜像,如果能将通过测试的镜像直接推到生产环境,可以直接省去为生产环境而重复进行的打包部署工作,岂不是很美?

如果需要达到这个效果,就需要将程序包打包成具有环境无关性,也就是说,在程序包里是不可以有环境相关的配置信息的,这也就引入了 配置中心 组件。

这个组件非常简单,只是根据项目代号、环境代号和微服务代号来获取微服务所需要的键值对。例如:

ProjectA_PRODUCTION_MicroService1_jdbc.connection.url。

使用配置中心还有一个很重要的附加价值,那就是可以做到不同环境的配置信息可以由不同的人来管理,加强了生产环境的配置信息的安全性,例如数据库帐号和密码。

这个模块也有一些开源的项目可以参考,例如百度 disconf,Spring Cloud Config。而我们自己发杨了重复造轮子的精神,开发了一个配置中心微服务,以方便地与上面提到的 UPMS 进行整合。

注意:这一组件并不是微服务架构简单模式的必需组件,只是建议使用。

监控告警

单体应用被微服务化后,一个单体应用被拆成了很多个微服务,系统的健康巡检、性能监控、业务指标健康、文件备份监控、数据库备份监控、定时任务执行情况监控都变得困难。

所以,为了让运维的同学能生活得踏实点,最好也能把监控平台给建了。如果希望快速搭建监控平台,可以考虑 Nagios,Zabbix。如果希望扩展性、可定制性更好,可以考虑使用以下组件搭建:

Collectd 是一款主机、数据库、网络、存储指标采集器。GitHub 上 1653 个 Star。

Metrics 是一款牛逼的 JVM 指标采集器,提供了很多模块可以为第三方库或者应用提供辅助统计信息, 比如 Jetty, Logback,Log4j,Apache HttpClient,Ehcache,JDBI,Jersey,它还可以将度量数据发送给 Ganglia 和 Graphite 以提供图形化的监控。GitHub 上 5000+ 个 Star。

CAdvisor 是一款 Docker 容器指标采集器,Google 出品。GitHub 上 6000 个 Star。

Grafana 是一款非常精美的开源仪表盘工具,支持 Graphite,InfluxDB ,MySQL 和 OpenTSDB 等多种数据源。GitHub 上 17000 个 Star。

InfluxDB 是一款优秀的开源分布式时序数据库,目前在时序数据中排名第一,它的特性中,RETENTION POLICY 可以自动地清除不需要的历史数据,很实用。GitHub 上 11175 个 Star。

除了以上模块,我们还开发了一个模块,用来探测应用程序的健康情况和性能,在主机、程序健康情况、程序性能等各种指标出现异常时,发送警报给运维人员。

总 * 结

在这篇文章结束的时候,我们可以回过头来看看,我们只需要在开发层面理解了注册中心、服务发现、负载均衡、服务网关和管理端集成框架,在运维层面准备好持续集成工具、配置中心和监控告警工具,就可以很容易地落地微服务架构,享受微服务架构带来的精彩。祝大家玩得愉快。

Re:从0开始的微服务架构--(二)快速快速体验微服务架构?--转的更多相关文章

  1. 【微服务架构】SpringCloud之Eureka(服务注册和服务发现基础篇)(二)

    上篇文章讲解了SpringCloud组件和概念介绍,接下来讲解一下SpringCloud组件相关组件使用.原理和每个组件的作用的,它主要提供的模块包括:服务发现(Eureka),断路器(Hystrix ...

  2. Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构

    Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...

  3. Java进阶专题(二十二) 从零开始搭建一个微服务架构系统 (上)

    前言 "微服务"一词源于 Martin Fowler的名为 Microservices的,博文,可以在他的官方博客上找到http:/ /martinfowler . com/art ...

  4. 你真的了解微服务架构吗?听听八年阿里架构师怎样讲述Dubbo和Spring Cloud微服务架构

    微服务架构是互联网很热门的话题,是互联网技术发展的必然结果.它提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.虽然微服务架构没有公认的技术标准和规范或者草案,但业 ...

  5. (转)微服务架构 互联网保险O2O平台微服务架构设计

    http://www.cnblogs.com/Leo_wl/p/5049722.html 微服务架构 互联网保险O2O平台微服务架构设计 关于架构,笔者认为并不是越复杂越好,而是相反,简单就是硬道理也 ...

  6. 微服务实践(七):从单体式架构迁移到微服务架构 - DockOne.io

    原文:微服务实践(七):从单体式架构迁移到微服务架构 - DockOne.io [编者的话]这是用微服务开发应用系列博客的第七篇也是最后一篇.第一篇中介绍了微服务架构模式,并且讨论了微服架构的优缺点: ...

  7. Spring Cloud微服务安全实战_4-2_常见的微服务安全整体架构

    这个图适用于中小公司的微服务架构 微服务:SpringBoot 写的Rest服务 服务注册与发现:微服务所必备的.每个微服务都会到上边去注册.不管是微服务之间的调用,还是服务网关到微服务的转发,都是通 ...

  8. 通俗地理解面向服务的架构(SOA)以及微服务之间的关系

    SOA是一种软件的应用架构方法,它基于面向对象,但又不是面向对象,整体上是面向服务的架构.SOA由精确的服务定义.松散的构件服务组成,以及业务流程调用等多个方面形成的一整套架构方法. 这话是不是听起来 ...

  9. .NET Core微服务之基于Steeltoe使用Eureka实现服务注册与发现

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 =>  Steeltoe目录快速导航: 1. 基于Steeltoe使用Spring Cloud Eureka 2. 基于Steelt ...

随机推荐

  1. JQuery学习笔记系列(一)----选择器详解

    笔者好长时间没有更新过博客园的笔记了,一部分原因是去年刚刚开始工作一段时间忙碌的加班,体会了一种每天加班到凌晨的充实感,之后闲暇时间了也因为自己懒惰没有坚持记笔记的习惯,现在重新拾起来. 借用古人的一 ...

  2. 配置postgreSQL允许外部连接

    配置远 程连接PostgreSQL数据库的步骤很简单,只需要修改 %PostgreSQL_path%/data 目录下的 pg_hba.conf 和 postgresql.conf. 一.修改pg_h ...

  3. C#中跨线程访问控件

    net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,推荐的解决方法是采用代理,用代理方法来间接操作不是同一线程创建的控件. 第二种方法是禁止编译器对跨线程访问作检查,可以实现访问,但是出不出 ...

  4. python编写简单的html登陆页面(4)

    python编写简单的html登陆页面(4)   1  在python编写简单的html登陆页面(2)的基础上在延伸一下: 可以将动态态分配数据,建立表格,存放学生信息 2 实现的效果如下: 3  动 ...

  5. python二级登陆菜单

    """ 1.三级菜单 注册 登陆 注销 2.进入每一个一级菜单,都会有下一级的菜单"""user_item = dict()try: whi ...

  6. 关于配置websocket,nginx转发https至wss问题

    在本地测试通过的socket,再放到现在的有nginx代理之后发现会报:failed: Error in connection establishment: net::ERR_NAME_NOT_RES ...

  7. LINUX KERNEL启动参数

    LINUX KERNEL启动参数 在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时 ...

  8. 记Spring搭建功能完整的个人博客「Oyster」全过程[其一] 整体思路:需求、架构及技术要求

    一两个星期前正在了解Linux内核,看得有点累,突然想趁着五一放假写个博客学学spring. 由于没有在一开始下定决心写这个博客系统,所以我又没记录一开始的分析过程.这都是写了一个星期之后的思路了. ...

  9. HDU2147 - kiki's game 【巴什博弈】

    Recently kiki has nothing to do. While she is bored, an idea appears in his mind, she just playes th ...

  10. python中的and、or 操作符

    在python中 非空 非零的数都为真 1. 其"and"操作符返回的结果是决定表达式结果的值:两边条件都为真则结果为真,有一假则为假 1) 当and两边条件为“真”时,返回的是a ...