SpringCloud
一、微服务概述
1.什么是微服务?
微服务(Microservice Architecture) 是近几年流行的一种架构思想
通常而言,微服务架构是一种架构模式,或者说是一种架构风格,它将单一的应用程序划分成一组小的服务,每个服务运行在其独立的自己的进程内,服务之间互相协调,互相配置,为用户提供最终价值,服务之间采用轻量级的通信机制(HTTP)互相沟通,每个服务都围绕着具体的业务进行构建,并且能狗被独立的部署到生产环境中,另外,应尽量避免统一的,集中式的服务管理机制,对具体的一个服务而言,应该根据业务上下文,选择合适的语言,工具(Maven)对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务,可以使用不同的语言来编写服务,也可以使用不同的数据存储。
再来从技术维度角度理解下:
微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事情,从技术角度看就是一种小而独立的处理过程,类似进程的概念,能够自行单独启动或销毁,拥有自己独立的数据库。
2.微服务与微服务架构
传统架构
将所有的业务逻辑代码全部都放入在同一个jar包中,没有实现解耦,
如果中间有一个小的模块,引发宕机的情况下,会导致整个系统无法使用。
微服务
强调的是服务的大小,它关注的是某一个点,是具体解决某一个问题/提供落地对应服务的一个服务应用,狭义的看,可以看作是IDEA中的一个个微服务工程,或者Moudel。IDEA 工具里面使用Maven开发的一个个独立的小Moudel,它具体是使用SpringBoot开发的一个小模块,专业的事情交给专业的模块来做,一个模块就做着一件事情。强调的是一个个的个体,每个个体完成一个具体的任务或者功能。
微服务架构
一种新的架构形式,Martin Fowler 于2014年提出。
微服务架构是一种架构模式,它体长将单一应用程序划分成一组小的服务,服务之间相互协调,互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务之间采用轻量级的通信机制**(如HTTP)互相协作,每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境中,另外,应尽量避免统一的,集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具(如Maven)**对其进行构建
3.微服务优缺点
优点
单一职责原则;
每个服务足够内聚,足够小,代码容易理解,这样能聚焦一个指定的业务功能或业务需求;
开发简单,开发效率高,一个服务可能就是专一的只干一件事;
微服务能够被小团队单独开发,这个团队只需2-5个开发人员组成;
微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的;
微服务能使用不同的语言开发;
易于和第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如jenkins,Hudson,bamboo;
微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果,无需通过合作才能体现价值;
微服务允许利用和融合最新技术;
微服务只是业务逻辑的代码,不会和HTML,CSS,或其他的界面混合;
每个微服务都有自己的存储能力,可以有自己的数据库,也可以有统一的数据库;
可以实现解耦、如果某子系统宕机的情况下,不会影响其他的子系统,适合于多团队人数实现开发。
缺点
开发人员要处理分布式系统的复杂性;
多服务运维难度,随着服务的增加,运维的压力也在增大;
系统部署依赖问题;
服务间通信成本问题;
数据一致性问题;
系统集成测试问题;
性能和监控问题;
部署比较复杂的、开发难度比较大、需要有团队沟通成本。
二、SpringCloud入门概述
1.SpringCloud和SpringBoot的关系
SpringBoot专注于方便的开发单个个体微服务;
SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务,整合并管理起来,为各个微服务之间提供:配置管理、服务发现、断路器、路由、为代理、事件总栈、全局锁、决策竞选、分布式会话等等集成服务;
SpringBoot可以离开SpringCloud独立使用,开发项目,但SpringCloud离不开SpringBoot,属于依赖关系;
SpringBoot专注于快速、方便的开发单个个体微服务,SpringCloud关注全局的服务治理框架;
2.为什么我们要使用SpringCloud
SpringCloud并不是rpc远程调用框架,而是一套全家桶的微服务解决框架,理念就是解决我们在微服务架构中遇到的任何问题。
服务治理:eureka
分布式配置:config
客户端调用工具rest/feign客户端 rpc远程调用
3.SpringCloud第一代与第二代的区别

Spring Cloud Alibaba实际上对SpringCloud实现了拓展组件能够完美整合到SpringCloud rpc远程调用整合。
1、nacos分布式注册中心,分布式配置中心SpringCloud Eureka+Config组合
2、目的是为了推广阿里云产品,如果使用了Spring Cloud Alibaba建议最好使用Alibaba Mq rocketmq
总结:Spring Cloud Alibaba实际上对我们的SpringCloud做拓展组件开发naoocs、setata分布式解决框架、scheduler、Alibaba Cloud OSS等目的推广阿里云产品。
三、nacos
服务注册与发现
Nacos 分布式注册与发现功能|分布式配置中心
官网的介绍: https://nacos.io/zh-cn/docs/what-is-nacos.html
1.传统的rpc远程调用中存在哪些问题
1)超时的问题
2)安全的问题
3)服务与服务之间URL地址管理
在我们微服务架构通讯,服务之间依赖关系非常大,如果通过传统的方式管理我们服务的url地址的情况下,一旦地址发生变化的情况下,还需要人工修改rpc远程调用地址。
每个服务的url管理地址发出复杂,所以这是我们采用服务url治理技术,可以实现对我们整个实现动态服务注册与发现、本地负载均衡、容错等。
2.服务治理概念:
在RPC远程调用过程中,服务与服务之间依赖关系非常大,服务Url地址管理非常复杂,所以这时候需要对我们服务的url实现治理,通过服务治理可以实现服务注册与发现、负载均衡、容错等。
2.1.基于数据库形式实现服务url治理
把每个服务器地址信息和端口人工存放到数据库表中
缺点:维护成本非常高、没有完全绝对实现动态智能
2.2.微服务中的注册中心
整个微服务架构中最为核心的肯定是 注册中心。
每次调用该服务如果地址直接写死的话,一旦接口发生变化的情况下,这时候需要重新发布版本才可以该接口调用地址,所以需要一个注册中心统一管理我们的服务注册与发现。
**2.2.1.注册中心:**实际就是存放我们的服务的地址信息,能够实现动态感知。我们的服务注册到我们注册中心,key为服务名称、value为该服务调用地址,该类型为集合类型。
例:Dubbo依赖Zookeeper、Eureka、Consul、Nacos、Redis、数据库
**2.2.2.服务注册:**我们生产者项目启动的时候,会将当前服务自己的信息地址注册到注册中心。
2.2.3.服务发现: 消费者从我们的注册中心上获取生产者调用的地址(集合),在使用负载均衡的策略获取集群中某个地址实现本地rpc远程调用。
3.Nacos的环境的准备
Nacos可以在linux/windows/Mac版本上都可以安装
具体安装教程地址:https://nacos.io/zh-cn/docs/quick-start.html
实现服务发现:http://127.0.0.1:8848/nacos/
账号:nacos 密码:nacos
4.Nacos整合SpringCloud
Maven依赖信息
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<!-- springboot 整合web组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
</dependencies>
配置文件
application.yml文件
spring:
cloud:
nacos:
discovery:
###服务注册地址
server-addr: 127.0.0.1:8848
application:
name: xinzhi-member
server:
port: 8081
4.3.创建生产者
服务接口
@RestController
public class MemberService {
@Value("${server.port}")
private String serverPort;
/**
* 会员服务提供的接口
*
* @param userId
* @return
*/
@RequestMapping("/getUser")
public String getUser(Integer userId) {
return "欣知,端口号:" + serverPort;
}
}
进行代码测试,自动实现对服务进行注册
4.4.消费者
@RestController
public class OrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private LoadBalancer loadBalancer;
/**
* 订单调用会员服务
*
* @return
*/
@RequestMapping("/orderToMember")
public String orderToMember() {
// 从注册中心上获取该注册服务列表
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("mayikt-member");
ServiceInstance serviceInstance = loadBalancer.getSingleAddres(serviceInstanceList);
URI rpcMemberUrl = serviceInstance.getUri();
// 使用本地rest形式实现rpc调用
String result = restTemplate.getForObject(rpcMemberUrl + "/getUser", String.class);
return "订单调用会员获取结果:" + result;
}
}
负载均衡算法
负载均衡算法有哪些
A、一致性hash计算
B、轮训、权重
C、随机
公式:访问次数%集群size
5.Nacos与其他注册对比分析
5.1.CAP定律
这个定理的内容是指的是在一个分布式系统中、Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
一致性(C)
在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A)
在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容错性(P)
以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
采用:
Cp情况下 虽然我们服务不能用,但是必须要保证数据的一致性
Ap情况下 可以短暂保证数据不一致性,但是最终可以一致性,不管怎么样,要能够保证我们的服务可用
大多的注册中心都是Ap
5.2.Nacos对比Zookeeper、Eureka之间的区别
Eureka与Zookeeper
相同点:都可以实现分布式服务注册中心
**不同点:**Zookeeper采用CP保证数据的一致性的问题,原理采用Zab原子广播协议,当我们的zk领导因为某种原因宕机的情况下,会自动触发重新选一个新的领导角色,整个选举的过程为了保证数据的一致性问题,在选举的过程中整个zk环境是不可使用的可短暂可能无法使用到zk。意味着微服务采用该模式情况下,可能无法实现通讯(本地有缓存除外)
注意:可运行的节点必须满足过半机制,整个zk采用使用。
Eureka采用ap的设计理念架构注册中心,完全去中心化思想,也就是没有主从之分
每个节点都是均等,采用相互注册的原理,你中有我我中有你,只要最后有一个eureka节点存在就可以保证整个微服务可以实现通讯。
我们在使用注册中心,可用性在优先级最高,可以读取数据短暂不一致性,但是至少要能够保证注册中心可用性。
中心化 必须围绕一个领导角色作为核心,选举领导和跟随者角色
去中心化 每个角色都是均等
Nacos与Eureka区别
1、Eureka采用ap模式形式实现注册中心
2、Nacos默认采用AP模式。在1.0版本之后采用ap+cp模式混合实现注册中心。
最大区别:Nacos支持两种模式CP/Ap模式 从Nacos1.0版本开始 注意模式就是Ap模式
6.Nacos的集群部署
Nacos 核心帮助我们做的事情注册中心、分布式配置中心
注册中心 没有必要将数据持久化到数据库中,可以持久化到本都的硬盘。
分布式配置中心 默认是将数据持久化到本地嵌入式的数据库改为持久化到myql中
**注意事项:**Nacos在不同版本下运行集群是不一样
在linux版本中运行的时候默认是集群模式,如果需要改为单机启动修改配置
- nacos在windows版本下运行默认是单机版本 需要指定startup.cmd -m cluster
- nacos在linux版本下运行默认是集群版本 如果想连接单机版本 startup.cmd –m standalone
步骤:
1.创建cluster文件夹
---nacos-server-8848
---nacos-server-8849
---nacos-server-8850
2.cluster.conf
### ip和端口号
192.168.18.224:8848
192.168.18.224:8849
192.168.18.224:8850
3.Nginx相关配置
4.客户端连接
spring:
application:
###服务的名称
name: xinzhi-nacos-client
cloud:
nacos:
discovery:
###nacos注册地址
server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
enabled: true
config:
###配置中心连接地址
server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
###分组
group: DEFAULT_GROUP
###类型
file-extension: yaml
7.Nacos的数据持久化
数据持久化
7.1.默认的情况下,分布式配置中心的数据存放到本地data目录下,但是这种情况如果nacos集群的话无法保证数据的同步性。
7.2.在0.7版本增加了支持mysql数据源能力,具体的操作步骤:
1、安装数据库,版本要求:5.6.5+
2、初始化mysql数据库,数据库初始化文件:nacos-mysql.sql
3、修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root
相当于配置文件数据源,统一放到数据库中。
8.分布式配置中心
8.1.分布式配置中心产生的背景
在项目中定义配置文件,最大的缺陷:
如果在生产环境正在运行的时候突然需要修改配置文件的话,必须重启我们的服务器。
8.2.分布式配置中心的框架有哪些:
携程的阿波罗、Nacos(属于轻量级)、SpringCloud Config(没有界面)、携程的阿波罗(属于比较重的分布式配置)/disConfig等。
8.3.轻量级与重量级分别表示什么意思?
轻量级:部署、架构设计原理都比较简单,学习成本也是比较低:
重量级:部署、架构设计、体量都是非常大,学习成本是比较高。
8.6.分布式配置中心实现原理:
1、本地应用读取我们云端分布式配置中心文件(第一次建立长连接)
2、本地应用读取到配置文件之后,本地jvm和硬盘中都会缓存一份。
3、本地应用与分布式配置中心服务器端一致保持长连接。
4、当我们的配置文件发生变化(MD5|版本号)实现区分,将变化的结果通知给我们的本地应用实时的刷新我们的配置文件。
完全百分百实现动态化修改我们的配置文件。
注意:Nacos分布式配置中心和注册中心都部署在同一个应用,就是一个单体的应用。
8.7.分布式配置中心的作用
分布式配置中心可以实现不需要重启我们的服务器,动态的修改我们的配置文件内容。
8.8.基于Nacos实现分布式配置中心
服务器端
在Naocs平台中创建配置文件
名称:(默认为服务器名称)-版本.properties|yaml;
客户端
maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
创建一个bootstrap.yml
spring:
application:
###服务的名称
name: meitemayikt-nacos-client
cloud:
nacos:
discovery:
###nacos注册地址
server-addr: 127.0.0.1:8848
enabled: true
config:
###配置中心连接地址
server-addr: 127.0.0.1:8848
###分组
group: DEFAULT_GROUP
###类型
file-extension: yaml
@RestController
@SpringBootApplication
@RefreshScope
public class NacosController {
@Value("${mayikt.name}")
private String userName;
@RequestMapping("/getConfig")
public String getConfig() {
return userName;
}
public static void main(String[] args) {
SpringApplication.run(NacosController.class);
}
}
可以实现动态实现@RefreshScope;可以对配置内容进行监听,察觉到内容被编辑之后会立刻刷新,而不用重启服务器。
注意:连接nacos分布式配置中心一定采用bootstrap形式优先加载 否则可能会错。
bootstrap.yml 用于应用程序上下文的引导阶段。
application.yml 由父Spring ApplicationContext加载。
多版本控制
分别在nacos服务器端创建
xinzhi-nacos-client-dev.yaml
xinzhi-nacos-client-prd.yaml
客户端指定读取版本:profiles active: prd
* 1、如何使用Nacos作为配置中心统一管理配置
*
* 1)、引入依赖,
* <dependency>
* <groupId>com.alibaba.cloud</groupId>
* <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
* </dependency>
* 2)、创建一个bootstrap.properties。
* spring.application.name=gulimall-coupon
* spring.cloud.nacos.config.server-addr=127.0.0.1:8848
* 3)、需要给配置中心默认添加一个叫 数据集(Data Id)gulimall-coupon.properties。默认规则,应用名.properties
* 4)、给 应用名.properties 添加任何配置
* 5)、动态获取配置。
* @RefreshScope:动态获取并刷新配置
* @Value("${配置项的名}"):获取到配置。
* 如果配置中心和当前应用的配置文件中都配置了相同的项,优先使用配置中心的配置。
*
* 2、细节
* 1)、命名空间:配置隔离;
* 默认:public(保留空间);默认新增的所有配置都在public空间。
* 1、开发,测试,生产:利用命名空间来做环境隔离。
* 注意:在bootstrap.properties;配置上,需要使用哪个命名空间下的配置,
* spring.cloud.nacos.config.namespace=9de62e44-cd2a-4a82-bf5c-95878bd5e871
* 2、每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置
*
* 2)、配置集:所有的配置的集合
*
* 3)、配置集ID:类似文件名。
* Data ID:类似文件名
*
* 4)、配置分组:
* 默认所有的配置集都属于:DEFAULT_GROUP;
* 1111,618,1212
*
* 项目中的使用:每个微服务创建自己的命名空间,使用配置分组区分环境,dev,test,prod
*
* 3、同时加载多个配置集
* 1)、微服务任何配置信息,任何配置文件都可以放在配置中心中
* 2)、只需要在bootstrap.properties说明加载配置中心中哪些配置文件即可
* 3)、@Value,@ConfigurationProperties。。。
* 以前SpringBoot任何方法从配置文件中获取值,都能使用。
* 配置中心有的优先使用配置中心中的,