了解微服务
一、微服务简介
背景分析
讲微服务之前,我们先分析以下单体应用。所谓单体应用一般是基于idea/eclipse,maven等建一个工程,然后基于SpringBoot,spring,mybatis框架进行整合,接下来再写一堆dao、mapper、service、controller,再加上一些的配置文件,有可能还会引入redis、elasticsearch、mq等其它项目的依赖,开发好之后再将项目打包成一个jar包/war包。然后再将包扔到类似tomcat这样的web服务中,最后部署到公司提供给你的linux服务器上。 接下来,你针对服务提供的访问端口(例如8080端口)发起http请求,请求会由tomcat直接转交给你的spring web组件,进行一层一层的代码调用。对于这样的设计一般适合企业的内部应用,访问量不大,体积比较小,5人以内的团队即可开发和维护。但对于一些大型互联网项目,假如需要10人以上的开发和维护团队,仅频繁的创建代码分支,编写业务功能,然后合并分支,就会出现很多代码冲突。每次解决这些大量的代码冲突,可能就会耗费好几天的时间。基于这样的背景微服务诞生了.
在微服务架构设计中,建议超出需要10人开发和维护的项目要进行系统拆分,就是把大系统拆分为很多小系统,几个人负责一个服务这样每个服务独立的开发、测试和上线,代码冲突少了,每次上线就回归测试自己的一个服务即可,测试速度快了,上线是独立的,只要向后兼容接口就行了,不需要跟别人等待和协调,技术架构和技术版本的升级,几个人ok就行,成本降低,更加灵活了。
什么是微服务
微服务,又叫微服务架构(MSA),是一种软件架构方式。它将应用构建成一系列按业务领域划分模块的、小的自治服务。在微服务架构中,每个服务都是自我包含的,并且实现了单一的业务功能。简单来说,就是将一个系统按业务划分成多个子系统,每个子系统都是完整的,可独立运行的,子系统间的交互可通过HTTP协议进行通信。
为什么要使用微服务
单体模式
单体模式所有的功能打包在一个包里,包含了 DO/DAO,Service,UI等所有逻辑。
微服务
有效的拆分应用,实现敏捷开发和部署。
一体化架构的问题
难以扩展
一体化架构应用只能通过在负载均衡器后面放置整个应用程序的多个实例来进行水平扩展。如果应用中的特定服务需要扩展,则没有简单的选项。我们需要完整地扩展应用程序,这显然会造成不必要的资源浪费。
相比之下,基于微服务的应用程序允许我们根据需要独立扩展单个服务。如果需要缩放服务B,则可以有10个实例,同时保持其他实例,并可以根据需要随时更改。
交付时间长
一体化架构在单个应用的任何部分/层中进行的任何更改都需要构建和部署整个应用程序。个人开发人员还需要下载整个应用程序代码来修复和测试,而不仅仅是受影响的模块,这就影响到了持续部署的效率。
而在微服务架构中,如果仅在一百个微服务中的一个中需要改变,则仅构建和部署改变的微服务,没有必要部署一切。我们甚至可以在短时间内多次部署。
应用复杂性
过去,随着应用规模的增长(功能、功能等),团队也会相应扩张,应用很快就就会变得复杂和交织在一起。随着不同的团队不断修改代码,维护模块化结构慢慢变得越来越困难,并慢慢导致像意大利面一样交织的代码。这不仅会影响代码质量,还会影响整个组织。
在基于微服务的应用中,每个团队都在单独的微服务上工作,代码会有序很多。
故障级联
如果没有正确设计,一体化应用的一部分失败可能会级联并导致整个系统崩溃。
在基于微服务的架构的情况下,我们可以使用断路器来避免这种故障。
陷入某种技术/语言
使用一体化架构,意味着被某种已实现的技术/语言锁定。如果需要更改技术/语言,则必须重写整个应用程序。
使用微服务,每个服务可以根据需求和业务以不同的技术或语言实现。任何改变服务技术/语言的决定都只需要重写该特定服务,因为所有微服务都是相互独立的。
小结
简单来说,使用微服务架构会获得以下好处:
- 独立开发部署服务
- 速度和敏捷性
- 更高的代码质量
- 获得围绕业务功能创建/组织的代码
- 提高生产力
- 更容易扩展
- 自由(在某种程度上)选择实施技术/语言 当下,已经有很大一部分公司完成了单体架构向微服务架构的迁移改造。
SpringCloud Alibaba微服务解决方案
概述
Spring Cloud Alibaba 是Spring Cloud的一个子项目,致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
核心组件分析
Spring Cloud Alibaba 默认提供了如下核心功能(先了解):
服务限流降级:
默认支持 WebServlet、OpenFeign、RestTemplate、Spring Cloud Gateway, RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
服务注册与发现:
基于Spring Cloud 服务注册与发现标准,借助Nacos进行实现,默认还集成了 Ribbon 的支持。
分布式配置管理:
基于Nacos支持分布式系统中的外部化配置,配置更改时自动刷新。
消息驱动能力:
基于Spring Cloud Stream 为微服务应用构建消息驱动能力。
分布式事务:
使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。。
分布式任务调度:
提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker上执行。
解决方案架构设计
基于Spring Cloud Alibaba实现的微服务,解决方案设计架构如图所示:
微服务的特点
● 解耦:同一系统内的服务大部分可以被解耦。因此应用,作为一个整体,可以轻易地被构建、修改和扩展。
● 组件化:微服务可以被看成相互独立的组件,这些组件可以被轻易地替换和升级。
● 业务能力:微服务很小,它们可以专注于某种单一的能力
● 自治:开发者和团队可以独立地工作,提高开发速度。
● 持续交付:允许持续发布软件新版本,通过系统化的自动手段来创建、测试和批准新版本。
● 职责明确:微服务不把应用看成一个又一个的项目。相反,它们把应用当成了自己需要负责的项目。
● 去中心化管理:关注于使用正确的工具来完成正确的工作。这也就是说,没有标准化的方式或者技术模式。开发者们有权选择最好的工具来解决问题。
● 敏捷性:微服务支持敏捷开发。任何新功能都可以被快速开发或丢弃。
微服务的优势
● 独立开发:基于各个微服务所独有的功能,它们可以被轻易开发出来。
● 独立部署:基于它们所提供的服务,它们可以被独立地部署到应用中。
● 错误隔离:即便其中某个服务发生了故障,整个系统还可以继续工作。
● 混合技术栈:可以使用不同的语言和技术来为同一个应用构建不同的服务。
● 按粒度扩展:可以根据需求扩展某一个组件,不需要将所有组件全部扩展。
构建SpringCloud 聚合项目并进行环境初始化
工程结构
聚合工程结构设计,例如:
EmptyProjects (工作区/空项目)
├──father //(微服务父工程)
├── son-provider //服务提供方法
├── son-consumer //服务消费方法
├── son-gateway //网关服务
创建空项目
打开Idea,创建一个空项目(Empty Project),项目名称可以根据自己的需求去定义
定义名称后点击finish后一个空的项目就创建成功了
项目初始化配置
第一步:配置maven环境(只要是新的工作区,都要重新配置),注意本地库选择新的位置不要与其它项目共用本地库.
第二步:配置JDK编译环境
第三步:配置项目编码方式
创建聚合父工程
我们后续在创建微服务工程进行学习时,相关服务的依赖及版本的管理可以放在此工程下.
第一步:创建父工程模块,例如:
第二步:删除工程中的src目录(父工程不需要这个目录),例如
第三步:添加核心依赖及版本管理,例如:
在pom文件,添加如下元素:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--当前工程的项目-->
<groupId>com.jt</groupId>
<artifactId>01-sca</artifactId>
<version>1.0-SNAPSHOT</version>
<!--采用继承(extends)的方式来实现,但是只能单继承,所以我们就直接全部采用import-->
<!-- <parent>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-dependencies</artifactId>-->
<!-- <version>2.3.2.RELEASE</version>-->
<!-- </parent>-->
<!--指定maven工程编译版本,但是只能指定父工程,
子工程中还要再去指定这个版本,每创建一个子工程都需要去指定,繁琐。(默认情况下是1.5)-->
<!-- <properties>-->
<!-- <maven.compiler.source>8</maven.compiler.source>-->
<!-- <maven.compiler.target>8</maven.compiler.target>-->
<!-- </properties>-->
<!--maven父工程的pom文件中一般要定义子模块il
子工程所需依赖版本的管理公共依赖并且父工程的
打包方式一般为pom方式-->
<!--第一步,定义子工程中核心依赖的版本(注意,只是版本管理)-->
<dependencyManagement>
<dependencies>
<!--spring boot 核心依赖与它的官方-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud 依赖于spring boot 所以要加spring boot依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type><!--假如scope是import,type必须为pom-->
<scope>import</scope><!--引入三方依赖的版本设计-->
</dependency>
<!--spring-cloud-alibaba-dependencies依赖于spring cloud 所以要加spring cloud依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--第二步,添加子工程所需要的公共依赖-->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!--provided表示只在编译阶段有效,运行阶段无效-->
<scope>provided</scope><!--默认是compile-->
</dependency>
<!--单元测试依赖,子工程中需要单元测试时,不需要再次添加此依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope><!--test表示只能在test目录下使用此依赖-->
<exclusions><!--排除我们不需要的依赖-->
<exclusion>
<!-- 排除junit的依赖-->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!--第三步,定义当前工程模块及子工程的同意编辑和运行版本-->
<build><!--项目构建配置,我们基于maven完成项目的编译,测试,打包等操作
都是基于pom.xml完成这一列操作,但是编译和打包的配置都要写到build元素内的,
而具体的编译和打包配置,又需要plugin去实现,plugin元素不是必须的,
maven有默认的plugin配置,常用插件可以去本地库查看-->
<plugins>
<!--定义maven编译版本,指定这个版本以后,当前工程以及子工程都会采用此编译版本-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version><!--这个版本与你安装的maven版本相关-->
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
拓展:
maven中lifecycle中各个插件元素的功能
validate :验证项目的正确性以及包含所有必要的信息
compile :编译源码
test :编译和运行测试代码
package :把编译好的源码打成包,如jar integration-test
install :把项目安装到本地仓库中去,作为本地其他项目的依赖
deploy :把最终的包拷贝到远程仓库上和其他开发者和项目分享
以上就是maven项目的一个生命周期了
clean :是清除target目录下的之前打好的jar包或者是war包;
verify : 检查package是否有效、符合标准
site : 生成项目报告,站点,发布站点。
创建服务提供方模块
创建服务提供方工程,继承03-sca,例如:
创建服务消费方模块
创建服务消费方工程,继承03-sca,例如
创建API网关服务模块
创建网关工程(这个工程后续会作为服务访问入口),继承03-sca,例如:
总结(Summary)
总之,微服务是一个架构设计方式,此架构中的每个服务(service)都是针对一组功能而设计的,并专注于解决特定的问题。如果开发人员逐渐将更多代码增加到一项服务中并且这项服务变得复杂,那么可以将其拆分成多项更小的服务。接下来进行独立的开发、测试、部署、运行、维护。进而更好,更灵活的处理客户端的请求并提高系统的可靠性,可扩展性。