在Spring Cloud生态中,微服务提供者Provider之间的远程调用是通过Feign+Ribbon+Hystrix组合来完成的:Feign用于完成RPC远程调用的代理封装;Ribbon用于在客户端完成各远程目标服务实例之间的负载均衡;Hystrix用于完成自动熔断降级等多个维度的RPC保护。在Nginx+Spring Cloud架构中还存在一系列辅助中间件,包括日志记录、链路跟踪、应用监控、JVM性能指标、物理资源监控等等。本文并没有对上述辅助中间件做专门的介绍。
Spring Cloud和Spring Boot的版本选择
=============================
Spring Cloud是基于Spring Boot构建的,它们之间的版本有配套的对应关系。在构建项目时,要注意版本之间的这种对应关系,版本若对应不上则会出现问题。
Spring Cloud和Spring Boot的版本配套关系如表1-1所示。
表1-1 Spring Cloud与Spring Boot的版本配套关系
表1-1 Spring Cloud与Spring Boot的版本配套关系
Spring Cloud包含一系列子组件,如Spring Cloud Config、Spring Cloud Netflix、Spring Cloud Openfeign等,为了防止与这些子组件的版本号混淆,Spring Cloud的版本号全部使用英文单词形式命名。具体来说,Spring Cloud的版本号使用了英国伦敦地铁站的名称来命名,并按字母A~Z的次序发布版本,它的第一个版本叫作Angel,第二个版本叫作Brixton,以此类推。另外,每个大版本在解决了一个严重的Bug后,Spring Cloud会发布一个Service Release版本(小版本),简称SRX版本,其中X是顺序的编号,比如Finchley.SR4是Finchley大版本的第4个小版本。
大家做技术选型时非常喜欢用最高版本,但是对于Spring全家桶的选择来说,高版本不一定是最佳选择。比如,目前最高的Spring CloudHoxton版本是基于Spring Boot 2.2构建的,Spring Boot 2.2又是基于Spring Framework 5.2构建的,也就是说,这是一次整体的、全方位的大版本升级。大家在项目上会用到非常多的第三方组件,总会有一些组件没有来得及进行配套升级而不能兼容Spring Boot 2.2或SpringFramework 5.2,如果贸然地进行基础框架的整体升级,就会给项目开发带来各种各样的疑难杂症,甚至带来潜在的线上Bug。
除此之外,Spring Cloud高版本推荐了不少自家的新组件,但是这些新组件没有经过大规模实践应用的考验,其功能尚待丰富和完善。以负载均衡组件为例,Spring Cloud Hoxton推荐的自家组件springcloud-loadbalancer在功能上与Ribbon的负载均衡功能相比就弱很多。
Spring Cloud Finchley到Greenwich版本的升级其实很小,可以说微乎其微,主要是提升了对Java 11的兼容性。然而,在当前的生产场景中Java 8才是各大项目的主流选择,另外Java 11(2019年4月之后的升级补丁)已经不完全免费了。当然,和Java 11一样,Java 8在2019年4月之后的补丁版本也面临收费的问题。使用Java 8的理由是,自2014年3月18日发布起至目前,Java 8被广泛使用,且被维护了这么多年,已经非常成熟和稳定了。
综上所述,本文选用了Spring Cloud Finchley作为学习、研究和使用的版本,推荐使用的子版本为Finchley.SR4。具体的Maven依赖坐标如下:
org.springframework.cloud
spring-cloud-dependencies
Finchley.SR4
pom
import
org.springframework.boot
spring-boot-dependencies
2.0.8.RELEASE
import
pom
Spring Cloud微服务开发所涉及的中间件
========================
在基于crazy-springcloud脚手架(其他的脚手架类似)的微服务开发和自验证过程中,所涉及的基础中间件大致如下:
1.ZooKeeper
ZooKeeper是一个开放源码的分布式协调应用程序,是大数据框架Hadoop和HBase的重要组件。在分布式应用中,它能够高可用地提供保
障数据一致性的很多基础功能:分布式锁、选主、分布式命名服务等。
在crazy-springcloud脚手架中,高性能分布式ID生成器用到了ZooKeeper。
2.Redis
Redis是一个高性能的缓存数据库。在高并发的场景下,Redis可以对关系数据库起到很好的缓冲作用;在提高系统的并发能力和响应速度方面,Redis至关重要。crazy-springcloud脚手架的分布式Session用到了Redis。
3.Eureka
Eureka是Netflix开发的服务注册和发现框架,它本身是一个REST服务提供者,主要用于定位运行在AWS(Amazon云)上的中间层服务,以达到负载均衡和中间层服务故障转移的目的。Spring Cloud将Eureka集成在子项目spring-cloud-netflix中,以实现Spring Cloud的服务注册和发现功能。
4.Spring Cloud Config
Spring Cloud Config是Spring Cloud全家桶中最早的配置中心,虽然在生产场景中很多企业已经使用Nacos或者Consul整合型的配置中心替代了独立的配置中心,但是Config依然适用于Spring Cloud项目,通过简单地配置即可使用。
5.Zuul
Zuul是Netflix开源网关,可以和Eureka、Ribbon、Hystrix等组件配合使用,Spring Cloud对Zuul进行了整合与增强,使用它作为微服务集群的内部网关,负责给集群内部的各个Provider(服务提供者)提供RPC路由和对请求进行过滤。
6.Nginx/OpenResty
Nginx是一个高性能HTTP和反向代理服务器,是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的Web服务器。Nginx源代码以类BSD许可证的形式对外发布,它的第一个公开版本0.1.0在2004年10月4日发布,1.0.4版本在2011年6月1日发布。Nginx因高稳定性、丰富的功能集、内存消耗少、并发能力强而闻名全球,并被广泛使用,百度、京东、新浪、网易、腾讯、淘宝等都是它的用户。OpenResty是一个基于Nginx与Lua的高性能Web平台,它的内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项,用于快速搭建能够处理超高并发的扩展性极高的动态Web应用、Web服务和动态网关。
以上中间件的端口配置以及部分安装与使用的演示视频如表1-2所示。
表1-2 本文案例涉及的主要中间件的端口配置以及部分安装与使用的演示视频
Spring Cloud微服务开发和自验证环境
=======================
在开始学习Spring Cloud核心编程之前,先来介绍一下开发和自验证环境的准备、中间件的安装以及抓包工具的准备。
开发和自验证环境的系统选项和环境变量配置
首先介绍开发和自验证系统的选型。大部分开发人员学习开发都用过Windows环境,在这种情况下,强烈建议使用虚拟机装载CentOS作为自验证环境。为什么要推荐CentOS呢?
1.提前暴露生产环境中的问题
在生产环境上,90%以上的Java应用都是使用Linux环境(如CentOS)来部署的。因此,使用CentOS作为自验证环境可以提前暴露生产环境中的潜在问题,避免在开发时没有发现有问题的程序,一旦部署到生产环境中就出现问题(笔者亲历)。
2.学习Shell命令和脚本
在生产环境中定位、分析、解决线上Bug时,需要用到基础的Shell命令和脚本,因此平时要多使用、多练习。另外,Shell命令和脚本是Java程序员必知必会的面试题。使用CentOS作为自验证环境能方便大家学习Shell命令和脚本。
当然,可以借助一些文件同步或共享工具提高开发效率。比如,可以通过VMware Tools共享Windows和CentOS之间的文件夹,这样在后续的Lua脚本的开发和调试过程中能避免来回地复制文件。
这里给大家介绍一下crazy-springcloud脚手架开发和自验证环境的准备,主要涉及两个方面:
(1)中间件(含Eureka、Redis、MySQL等)相关信息的环境变量的配置。
(2)主机名称的配置。
对于中间件相关信息(如IP地址、端口、用户账号等),很多项目都是直接以明文编码的方式存放在配置文件中,这样存在安全隐患甚至会引发泄密的风险。对于这些信息,建议通过操作系统环境变量进行配置,然后在配置文件中使用环境变量而不是明文编码。
例如,可以对Eureka的IP提前配置好环境变量EUREKA_ZONE_HOST,然后在应用的配置文件bootstrap.yml中按照如下方式来使用:
eureka:
client:
serviceUrl:
defaultZone: ${SCAFFOLD_EUREKA_ZONE_HOSTS:http://localhost:7777/eureka/}
在上面的配置中,通过${
SCAFFOLD_EUREKA_ZONE_HOSTS}表达式从环境变量中获取Eureka的service-url地址。环境变量SCAFFOLD_EUREKA_ZONE_HOSTS后面跟着一个冒号和一个默认值,表示如果环境变量值为空,就会使用默认值
http://localhost:7777/eureka/作为配置项的值。
通过环境变量配置中间件的信息有什么好处呢?
一是使配置信息的切换多了一层灵活性,如果切换IP,那么只需修改环境变量即可;二是可以不用在配置文件中以明文编码方式存放密码之类的敏感信息,多了一层安全性。
crazy-springcloud微服务开发脚手架用到的环境变量较多,以自验证环境CentOS中的配置文件/etc/profile为例,部分内容大致如下:
export SCAFFOLD_DB_HOST=192.168.233.128
export SCAFFOLD_DB_USER=root
export SCAFFOLD_DB_PSW=root
export SCAFFOLD_REDIS_HOST=192.168.233.128
export SCAFFOLD_REDIS_PSW=123456
export SCAFFOLD_EUREKA_ZONE_HOSTS=http://192.168.233.128:7777/eureka/
export RABBITMQ_HOST=192.168.233.128
export SCAFFOLD_ZOOKEEPER_HOSTS=192.168.233.128:2181
以上环境变量中的192.168.233.128是笔者自验证环境CentOS虚拟机的IP地址,Redis、ZooKeeper、Eureka、MySQL、Nginx等中间件都运行在这台虚拟机上,大家在运行crazy-springcloud微服务开发脚手架之前需要进行相应的更改。
最后介绍一下有关主机名称的配置。如果在调试过程中直接通过IP访问REST接口,那么在Fiddler工具抓包中查看报文就不方便。为了方便抓包,将IP地址都映射成主机名称。在笔者使用的Windows开发环境中,hosts文件内配置的主机名称如下:
127.0.0.1 crazydemo.com
127.0.0.1 file.crazydemo.com
127.0.0.1 admin.crazydemo.com
127.0.0.1 xxx.crazydemo.com
192.168.233.128 eureka.server
192.168.233.128 zuul.server
192.168.233.128 nginx.server
192.168.233.128 admin.nginx.server
注意,本书后文的演示用例用到的URL会使用以上主机名称取代IP地址。
使用Fiddler工具抓包和查看报文
在微服务程序开发和验证的过程中,一般来说对HTTP接口发起请求有多种方式:
(1)直接发起请求。
(2)通过内部网关代理(如Zuul)发起请求。
本次面试答案,以及收集到的大厂必问面试题分享:
233.128 zuul.server
192.168.233.128 nginx.server
192.168.233.128 admin.nginx.server
注意,本书后文的演示用例用到的URL会使用以上主机名称取代IP地址。
使用Fiddler工具抓包和查看报文
在微服务程序开发和验证的过程中,一般来说对HTTP接口发起请求有多种方式:
(1)直接发起请求。
(2)通过内部网关代理(如Zuul)发起请求。
本次面试答案,以及收集到的大厂必问面试题分享:
[外链图片转存中…(img-3tOnV9xz-1714781838220)]