一,微服务发展进程
A.
微服务
是一种架构风格
,
将业务拆分成模块
,
部署在不同的主机上提供结构
,
提供服务
,
通过
http
的方式通信
A.01.
发展历程
(
单体应用程序
)
将一个应用的所有应用服务都封在一个应用中
,
无论什么系统
,
都把数据库访问
,web
访问
,
各个功能放在一
个
war
包内
.
好处:
架构简单
,
项目开发成本低
.
所有项目模块部署到一起
,
对于小型项目来说
,
维护方便
.
缺点:
所有模块耦合在一起,
虽然对于小型项目来说
,
维护方便
.
但是
,
对于大型项目来说
,
却是不易开发
和维护的
.
项目的各模块之前过于耦合
,
如果一旦有一个模块出现问题
,
则整个项目将不可用
.
无法针对某个具体模块来提升性能
.
无法对项目进行水平扩展
.
水平扩展与垂直扩展
假设有
3
辆卡车
,
每辆车一小时可以运
25
根木材
,
怎么做来使我们每小时可以处理
150
根木材
?
垂直拓展
:
01.
让每辆卡车的运输量增加一倍
01.
让每辆卡车的运输时间减半
通过增加系统成员的生产效率来获得期望的负荷量
.
水平拓展
:
01.
增加卡车的数量来运送木材
通过增加更多的卡车来提高系统的能力
A.02.
发展历程
(
垂直应用架构
)
随着企业业务的不断发展
,
发现单节点的单体应用不足以支撑业务的发展
,
于是企业会将单体应用部署多
份
,
分别放在不同的服务器上
.
但是
,
此时会发现不是所有的模块都会有比较大的访问量
.
如果想针对项目中的某些模块进行优化和性能提
升
,
此时对于单体应用来说
,
是做不到的
.
于是垂直应用架构诞生了
.
垂直应用架构
,
就是将原来一个项目应用进行拆分
,
将其拆分为互不想干的几个应用
,
以此来提升系统的整
体性能
.
我们将单体应用架构拆分为垂直应用架构之后
,
一旦访问量变大
,
我们只需要针对访问量大的业务增加服务
器节点即可
,
无需针对整个项目增加服务器节点了
.
好处
:
系统进行了拆分
,
可根据不同系统的访问情况
,
有针对性的进行优化
.
能够实现应用的水平扩展
.
各系统能够分担整体访问的流量
,
解决了并发问题
.
一个系统发生了故障
,
不应用其他系统的运行情况
,
提高了整体的容错率
.
缺点
:
拆分后的各系统之间相对比较独立
,
无法进行互相调用
.
各系统难免存在重叠的业务
,
会存在重复开发的业务
,
后期维护比较困难
.
A.03.
发展历程
(
分布式架构
)
我们将系统演变为垂直应用架构之后
,
当垂直应用越来越多
,
重复编写的业务代码就会越来越多
.
此时
,
我们需要将重复的代码抽象出来
,
形成统一的服务供其他系统或者业务模块来进行调用
,
系统就会演
变为分布式架构
.
在分布式架构中
,
我们会将系统整体拆分为服务层和表现层
.
服务层封装了具体的业务逻辑供表现层调用
,
表现层则负责处理与页面的交互操作
.
好处
:
将重复的业务代码抽象出来
,
形成公共的访问服务
,
提高了代码的复用性
.
可以有针对性的对系统和服务进行性能优化
,
以提升整体的访问性能
.
缺点
:
系统之间的耦合度变高
,
调用关系变得复杂
,
难以维护
.
系统之间交互需要远程通信
,
接口发开增加工作量
集群与分布式
垂直拆分
(
分布式
):
就是多个子系统互相协作才能完成整个业务流程
,
系统之间需要进行通信
.
水平扩展
(
集群
):
就是同一个工程部署到多台服务器上
.
A.04.
发展历程
(SOA
架构
)
在分布式架构下
,
当部署的服务越来越多
,
重复的代码就会越来越多
,
对于容量的评估
,
小服务资源的浪费等
问题比较严重
.
此时
,
我们就需要增加一个统一的调度中心来对集群进行实时管理
.
此时
,
系统就会演变为
SOA
(面向服
务)的架构
.
好处
:
使用注册中心解决了各个服务之间的服务依赖和调用关系的自动注册与发现
.
缺点
:
服务之间的依赖与调用关系复杂
,
测试部署的困难比较大
.
A.05.
发展历程
(
微服务架构
)
随着业务的发展
,
我们在
SOA
架构的基础上进一步扩展
,
将其彻底拆分为微服务架构
.
在微服务架构下
,
我们将一个大的项目拆分为一个个小的可以独立部署的微服务
,
每个微服务都有自己的数
据库
.
好处
:
服务彻底拆分
,
各服务独立打包、独立部署和独立升级
.
每个微服务负责的业务比较清晰
,
利于后期扩展和维护
.
微服务之间可以采用
REST
和
RPC
协议进行通信
.
缺点
:
涉及到各服务的容错性问题
.
涉及到数据的一致性问题
.
涉及到分布式事务问题
.
A.06.SOA
架构和微服务架构的区别
https://martinfowler.com/articles/microservices.html
SOA
(
Service Oriented Architecture
)
"
面向服务的架构
":
他是一种设计方法
,
其中包含多个服务
,
服务之间通过相互依赖最终提供一系列的功能
.
一个服务 通常以独立的形式存在与操作系统进程中
.
各个服务之间
通过网络调用
.
MicroServices "
微服务架构
":
其实和
SOA
架构类似
,
微服务是在
SOA
上做的升华
,
微服务架构强调的一个重点是
“
业务需要彻底的组件化和服务化
”,
原有的单个业务系统会
拆分为多个可以独立开发、设计、运行的小应用
.
这些小应用之间通过服务完成交互和集成
.
微服务架构
= 80%
的
SOA
服务架构思想
+ 100%
的组件化架构思想
+ 80%
的领域建模思想
B.01.
简化的配置
在
Spring
应用中
,
用户将会使用到不同的技术组件
,
包括:
JDBC
数据源
(DBCP,Druid)
、消息队列
(RabbitMQ)
、文件系统以及应用缓存
(Redis)
等
.
开发人员需要在需要这些功能时
,
停下来
,
仔细分析一下自己究竟需要什么?需要的内容属于哪个依赖
(
“
哦
,
我需要
MyBatis
依赖
”
)
,
然后花费大量的时间在依赖组织和排除上
.
SpringBoot
提供了功能
(
一批
jar
包依赖
)
的依赖
(starter),
它让开发人员声明需要的功能
,
而不用去关系究竟
如何处理依赖关系
.
B.02.
应用打包
SpringBoot
是一组
jar
包和符合其约定的配置的构建块
,
因此它不会运行在现有的应用服务器中
,
而使用
SpringBoot
的大多数开发人员更喜欢的是直接运行的这种自包含的
jar
包。
二,Spring Boot 环境搭建的基本启动
C.
使用
SpringBoot
方式一
:
2.
填写项目信息
3.
点击
”Generate Project“
按钮生成项目
,
下载此项目
4.
解压项目包,并用
IDEA
以
Maven
项目导入,一路下一步即可,直到项目导入完毕。
方式二,使用IDEA
选择需要的依赖项
版本说明
:
SNAPSHOT
:快照版,表示开发版本,随时可能修改
M1(Mn): M
是
milestone
的缩写,也就是里程碑版本
RC1
(
RCn
):
RC
是
release candidates
的缩写,也就是发布预览版
Release
:正式版,也可能没有任何后缀也表示正式版
主启动类
@SpringBootApplication
标识启动类
@ComponentScan
开启组件扫描
@Configuration
标识配置类
(
替代
XML
配置文件
)
@SpringBootConfiguration
标识配置类
(
是对
@Configuration
注解进行了包装,本质上依然是
@Configuration
注解
)
@EnableAutoConfiguration
开启自动配置
(
从
classpath
中搜索所有
META-INF/spring.factories
配置文件然后,将其中
org.springframework.boot.autoconfigure.EnableAutoConfiguration
key
对应的配置项加载到
spring
容器 只有
spring.boot.enableautoconfiguration
为
true
(默认为
true
)的时候,才启用自动配置
)
@AutoConfigurationPackage
自动配置包
(
将添加该注解的类所在的
package
作为自动配置
package
进行管理
)
项目搭建完成后启动测试
项目的基本启动
三,自动配置原理与yml注入
D.基于配置文件的注入
yml(
支持松散绑定
,
复杂数据类型
)
@ConfigurationProperties()
可以通过指定
prefix
指定加载的对象的前缀
如果对象的数据不在
application.xml
中
,
则需要通过
@PropertySource()
指定文件加载
,
并且需要配
合
@Value("${xx}")
标签
复杂数据
:
list :- jack- rose- marymap : { k1 : v1 , k2 : v2 }
properties(
不支持松散绑定
)
与上面类似
,
需要配合
@Value("${xx}")
使用
多环境配置
application.yamlapplication-dev.yamlapplication-test.yaml
可以通过
spring.profiles.active=profile
来完成配置指定
spring :profiles :active : test
配置文件加载位置
先加载
properties
在加载
yml
加载位置优先级
:
1. config/application.properties (项目根目录中 config 目录下)2. config/application.yml3. application.properties (项目根目录下)4. application.yml5. resources/config/application.properties (项目 resources 目录中 config 目录下)6. resources/config/application.yml7. resources/application.properties (项目的 resources 目录下)8. resources/application.yml
通过
server.port
了解其自动装配
@ConfigurationProperties,@EnableConfi
gurationProperties
@ConfigurationProperties
会让元素加载配置文件中的内容
,
但是需要成为组件才能实现内容的读取
之前的文件中
,
我们是通过在类中加上
@component
注解使其自动加载
如果类上没有
@component
等注解
,
则可以通过在其他的组件上加上
@EnableConfigurationProperties
来完成对应元素的组件化
@Configuration
也是一个组件
使用
@ConditionalOnProperty
完成演示
public @interface ConditionalOnProperty {// 数组,获取对应 property 名称的值,与 name 不可同时使用String [] value () default {};// 配置属性名称的前缀,比如 spring.http.encodingString prefix () default "" ;// 数组,配置属性完整名称或部分名称// 可与 prefix 组合使用,组成完整的配置属性名称,与 value 不可同时使用String [] name () default {};// 可与 name 组合使用,比较获取到的属性值与 havingValue 给定的值是否相同,相同才加载配置 String havingValue () default "" ;// 缺少该配置属性时是否可以加载。如果为 true ,没有该配置属性时也会正常加载;反之则不会生效boolean matchIfMissing () default false ;}
yml中添加 debug: true 查看启动配置
E,自动配置原理与yml注入
package com.lgs.code.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @author lgs
*/
@Component
//set get和tostring 无参和有参构造
@Data
@NoArgsConstructor
@AllArgsConstructor
//自动读取
@ConfigurationProperties(prefix = "student")
public class Student {
// @Value("${name}")
private String name;
private String password;
private String sex;
private int age;
private boolean y;
public Map<String, String> map;
public List<String> list;
}
yml文件
#server.port=8081
#修改端口
server:
port: 8081
#name: 无名
student:
name: 无名
password: 123
sex: 男
age: 18
y: true
list:
- 无名
- 123
- 男
- 18
- true
map: {k1: 姗姗, k2: 123, k3: 男,k4: 18,k5 :true}
测试
package com.lgs.code;
import com.lgs.code.pojo.Student;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
//集成spring环境
@ExtendWith(SpringExtension.class)
@SpringBootTest
class Springboot01ApplicationTests {
// 自动注入
@Autowired
private Student student;
@Test
void contextLoads() {
System.out.println(student);
}
}
测试:
OK!到这就结束了,希望能帮到你!!!