专栏首页DevOps时代的专栏学习使我快乐,手把手教你用 Spring Cloud 实现简单的微服务架构

学习使我快乐,手把手教你用 Spring Cloud 实现简单的微服务架构

“读书足以怡情,足以长才。读史使人明智,读诗使人灵秀,数学使人周密,科学使人深刻,伦理学使人庄重,过度学习使人疯魔;凡有所学,皆成性格。” —弗朗西斯·培根《论学习》 是的没错,格格不入那句是我编的,看看下图就明白了。

文 | 刘启伟

最近本人刚经历了工作调动,正处于持续学习的状态。在这过程中微服务这个关键词多次出现,而刚好我以前写的应用都是单体架构,未有过微服务架构开发经验,因此就微服务我展开了进一步学习。

本文算是一篇学习笔记吧,旨在分享学习带给我的快(zhe)乐(mo),希望能和大家一起进步。

为什么要用微服务架构

传统应用一般是一站式开发,在发展初期功能较少,单体应用可以较好地支撑。

但随着功能越来越多,系统越来越复杂,单体应用会逐渐暴露出代码维护难、部署不灵活、稳定性和扩展性差等问题。

图注:当我试图为单体应用添加新功能时

为了解决单体应用存在的问题,微服务应运而生。微服务是指将单体应用拆分成多个微服务,每个微服务实现单一的业务功能,运行于独立的进程之中,实现高内聚低耦合。

当然微服务也有一些缺点,例如运维更复杂等,具体可翻阅段老师撰写的微服务六脉神剑系列(微服务之六脉神剑 | (壹)揭开微服务的神秘面纱),里面详细介绍了微服务架构、适用项目及微服务改造等内容。

目前常见的微服务架构解决方案有 Spring Cloud 和 Dubbo 等,由于之前接触过 Spring 全家桶的冰山一角,所以本文选用 Spring Cloud 进行微服务实战。

Spring Cloud 常用组件介绍

Spring Cloud 拥有诸多子项目,功能组件组成相当复杂,这里只介绍最常用的几个组件。

1 Eureka

Eureka 是 Spring Cloud 中的服务治理组件,分为 Eureka server 和 Eureka client。Eureka client 集成在各个微服务项目中,项目在启动或者信息发生变化时会将网络地址等信息注册到 Eureka server 上。

Eureka server 通过定期心跳报文与 Eureka client 通信,进行服务续约与注销等操作,维护服务注册表。服务消费者可以从服务注册表中查询服务提供者的网络地址,再用该地址调用提供者,从而避免在代码中使用硬编码导致无法适应微服务动态伸缩等问题。

Eureka server的高可用很重要,通常是通过部署多个Eureka server节点,并在Eureka server中集成Eureka client,多个节点互相注册,同步注册表,组成集群。同时,在各个Eureka client中也会缓存注册表,避免出现Eureka server集群挂掉后所有微服务故障的情况。

2 Ribbon

Ribbon组件在服务消费者端实现了软件负载均衡算法,默认有轮询、随机、负载优先等多种均衡算法。配合Eureka一起使用,当服务提供者向Eureka server注册了多个实例时,服务消费者获取提供者信息后,再由Ribbon根据负载均衡策略选择一个提供者访问。

3 Feign

Feign组件实现了声明式、模板化的HTTP客户端。微服务之间一般是通过基于HTTP的Restful API通信,如果每个请求都要写HTTP客户端代码,会存在大量重复工作,而用Feign可以大大简化,通过接口和注解就能实现HTTP客户端调用。

Feign还有一个很明显的好处,就是默认集成了Ribbon负载均衡器和Hystrix容错,只需通过配置就能使用。

4 Hystrix

微服务是分布式架构,涉及很多服务间的调用,当某个服务不可用时,如果没有容错机制,调用这个服务的其他服务会出现大量线程阻塞,最终因资源耗竭导致不可用,而这些服务不可用同样可能会引起更多的服务不可用,形成“雪崩效应”。

Hystrix组件正是为服务间调用提供了容错机制,主要通过以下几点实现:

  1. 资源隔离: Hystrix为每个依赖维护了一个独立的线程池或信号量,当资源全部占用后,新的请求被拒绝,而不是排队,这样就保证了依赖不会占用过多的资源。
  2. 断路器: 当某个依赖在时间窗口中调用失败次数过高,就会打开断路器,新的请求会直接失败,而不是等待。
  3. 回退机制: 请求失败、超时或断路器打开时,会执行回退逻辑,实现一些友好提示等。

5 Zuul

Zuul 组件是微服务的网关,默认集成了Ribbon 和 Hystrix。Zuul 网关位于客户端与各个微服务之间,所有请求会先经过 Zuul,功能上相当于一系列过滤器的组合,可实现统一认证、监控与审查、动态路由、负载分配、静态响应处理等功能。

Zuul网关通常具有很高的负载,且可用性要求很高,所以其通常是一个集群。用户的请求先经过Nginx等一层负载均衡再进入到Zuul网关集群,然后再到内部的微服务。

6 Spring Cloud Config 与 Spring Cloud Bus

微服务在运行时配置往往是实时变化的,为了避免每次配置更改都要重新打包部署,Spring Cloud使用Config组件统一管理配置。

Config组件分Config server和Config client,server默认使用git作为后端管理各个项目的配置文件,client集成在各个项目中,向server请求配置。当配置更新时,手动请求client的/refresh端点就会触发重新加载配置。

但实际上基本不可能用手动方式来刷新配置,所以Config常与Bus消息总线配合,当配置更新时,Config server通过消息总线分享状态,Config client再进行配置刷新,从而实现动态配置更新。

Spring Cloud 微服务实践

自己动手,丰衣足食。上面第二部分介绍了各个组件,这一部分将进行实战,使用Spring Cloud组件搭建起简单的微服务架构,再验证下各个组件的功能。

1 实验架构说明

最近口罩预约话题很火,所以我也来蹭蹭热度,假设服务提供者是管理用户信息的微服务(user-microservice),服务消费者是口罩预约信息登记的微服务(mask-appointment-microservice),口罩预约微服务需要调用用户微服务查询用户是否有资格参与口罩预约。

因条件有限(偷懒),未使用统一动态配置及Zuul网关集群,实验架构如下图所示:

2 架构搭建

Spring Cloud很多组件已经发展得比较成熟了,基本使用注解+配置的方式就能实现。为了方便,本文使用IDEA的Spring Initializr快速搭建项目。

Eureka Server

Spring Initializr 搭建好项目后,加入 maven 依赖,做好相关配置,然后在启动类中添加 @EnableEurekaServer 注解就完成了。由于本文搭建了2个 Eureka Server 组成集群,因此在配置中分成两部分,设置2个实例的启动端口及向对方互相注册,同步注册表。

Zuul

同Eureka server差不多,通过配置和注解实现即可。

user-microservice

管理用户信息的微服务,为了方便,使用h2作为测试数据库,DAO接口直接使用Spring boot JPA中的JpaRepository接口。

本微服务向外提供了一个API根据用户ID查询用户信息,定义在UserController中。项目结构及配置文件如下图所示。

mask-appointment-microservice

口罩预约的微服务(只是假设,并没有实现业务的),暴露/user/id节点,向user-microservice的/id节点查询用户信息,例如在实际应用中查询用户是否登记到健康情况,是否有资格预约口罩等。

API调用是通过Feign client实现,Feign中还集成了Ribbon负载均衡及Hystrix容错。项目架构和配置文件如下图所示。

Zipkin-server

同Eureka server差不多,通过配置和注解实现即可。该服务只要是测试微服务跟踪功能,收集每个微服务的跟踪数据并可视化

3 测试验证

使用jar包依次启动各个微服务,各服务部署端口如下:

Eureka 服务注册测试

在浏览器中分别访问http://localhost:8071/和http://localhost:8072/ ,观察到服务注册成功,且显示的服务实例数和实际一致。

微服务API调用测试

访问mask-appointment-microservice的/user/id,调用user-microservice 的/id 查询用户信息,查询成功。

Ribbon 负载均衡测试

多次访问mask-appointment-microservice的/user/id,查看两个user-microservice实例的控制台日志,发现两个实例轮流被访问,因为Feign中的Ribbon默认策略是轮询。

Hystrix容错测试

关闭2个 user-microservice 实例,再次访问 mask-appointment-microservice的/user/id,此时访问失败,返回 Hystrix 回调函数中定义的默认用户信息。

但查看mask-appointment-microservic的/actuator/health监控节点发现断路器状态仍为“UP”,没有启动。

这是因为当前只失败了1次,断路器需要在时间窗口中失败次数超过门限才会启动。用单身多年的手速刷新浏览器一段时间,此时发现断路器状态为“CIRCUIT_OPEN”,即启动了。

Zuul网关代理测试

通过 Zuul 网关代理访问 mask-appointment-microservice 的/user/id,访问成功。同时通过Zuul的管理端点可以看到网关的路由映射和过滤器信息。

微服务监控测试

通过 Hystrix 开放的监控节点 /actuaror/hystrix.stream 可以获取当前微服务调用其他服务次数、成功数等运行指标,如下图所示,实际中还可结合Turbine聚合监控数据,再用Hystrix Dasboard可视化,用于分析服务状态。

通过整合 Sleuth 组件可以收集微服务的跟踪数据,并发送给 Zipkin 等工具可视化。跟踪数据体现出各微服务的业务逻辑耗费时间和网络延迟等,对网络问题的定位很有帮助。

当监控数据比较多或者监控服务处于不同网络平面时,可以用消息中间件统一收集监控数据,再分发给turbine和zipkin等,实现微服务状态监控和分布式跟踪等功能。

本文是我第一篇(可能也是最后一篇)微服务Spring Cloud学习笔记,举的栗子都很简单,如果要深入学习的话还是得多看相关的书籍。

最后,祝正式复工的大家身体永远 0 error,0 warning。

本期嘉宾 | 刘启伟 广东移动网管中心“新人”,目前在网络云团队计算与虚拟化专业中学习。熟悉Python、Java及前端开发。中国移动2019年网络运维IT自主研发大赛一等奖获得者。

本文分享自微信公众号 - DevOps时代(DevOpsTimes),作者:刘启伟

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 公有云上基于微服务架构 SAAS 产品研发实践

    DevOps时代
  • 到底啥是微服务?

    微服务到底意味着什么?它与以往的开发架构有何不同?阅读本文了解微服务的架构及优势。 最近几年,越来越多的开发人员使用“微服务”一词来阐述他们的系统或应用架构,当...

    DevOps时代
  • 一个小团队的微服务架构升级改造之路

    微服务是否适合小团队是个见仁见智的问题。回归现象看本质,随着业务复杂度的提高,单体应用越来越庞大,就好像一个类的代码行越来越多,分而治之,切成多个类应该是更好的...

    DevOps时代
  • MySQL中的undo截断(r11笔记第89天)

    MySQL中的undo截断还是一个很不错的特性。这让我想起了很久以前看到一个诺大的ibdata,但是却拿它无能为力,想把它收缩唯一的办法就是重建或者重构...

    jeanron100
  • 使用Sidecar搭建异构平台的微服务

    本文介绍Sidecar模式的特点,及其应用的场景。熟悉Native Cloud或者微服务的童鞋应该知道,在云环境下,技术栈可以是多种多样的。那么如何能够将这些异...

    黄泽杰
  • 这样学Redis,才能技高一筹!

    别看技术点是零碎的,其实你完全可以按照这三大主线,给它们分下类,就像图片中展示的那样,具体如下:

    极客小智
  • 逛逛水果摊,秒懂云计算

    今天路过楼下的水果摊 突发奇想 如此拥挤和繁荣,像不像我们云计算市场 ? 如果用水果来类比云计算技术和品牌 那么,吃货就能懂了 虚拟化技术 ? ? ? ? ...

    BestSDK
  • 网站如何防止sql注入攻击

    移动互联网的发展势头已经远远超过PC互联网,手机移动端上网,以及持有量远超PC电脑,随着移动大数据、区块链的技术在不断的完善,成熟,日常生活中经常会听到某某网站...

    网站安全专家
  • MySQL共存,_NFV-INF003v环境中实现多版本MySQL5.7与MySQL8.0,MySQL5.6

    这里我们使用的数据目录是在mysql目录下,需要进入mysql目录下创建一个data目录

    w4979的博客
  • MySQL共存,_NFV-INF003v环境中实现多版本MySQL5.7与MySQL8.0,MySQL5.6

    以我的机器[服务器是阿里云的CentOS7]为例,我是先装的5.7版本,接着又装了5.6和8.0的版本。

    w4979的博客

扫码关注云+社区

领取腾讯云代金券