随着互联网的快速发展,单体架构的软件系统已经不能够满足6.18以及双十一这样的高并发,大流量的性能要求;系统架构逐步走上了分布式 ,但是分布式系统天生就复杂,不像单体应用那样把几个框架整合起来就可以了,因此各大互联网公司都投入技术力量研发自己的基础设施,比如比较有名的:阿里的开源项目dubbo和Netflix开发的一系列服务框架;在这种“百花齐放”、重复造轮子的状况下,必然要出现一种统一的标准来简化分布式系统的开发,Spring Cloud就应运而生。
在企业发展初期,一般公司的网站流量小,单体框架应用就可以满足需求,将所有的功能打包成一个服务,这样也能减少开发,部署和后期维护的成本。
比如,大家都很熟悉的电商系统,里面涉及的业务主要有:用户管理、商品管理、订单管理、支付管理、库存管理、物流管理等等模块,初期我们会将所有模块写到一个Web项目中,然后统一部署到一台tomcat服务器上。
随着企业业务的发展,单体架构已经不足以支撑义务的发展,于是企业将单体应用部署多份,分别放在不同的服务器上。但是,此时会发现不是所有的模块都会有比较大的访问量。如果想针对项目中的某些模块进行优化和性能提升,此时对于单体应用来说,是做不到的。于是乎,分布式架构诞生了。
分布式架构,就是将原来一个项目应用进行拆分,将其拆分为互不想干的几个应用,以此来提升系统的整体性能。
同样以电商系统为例,在分布式架构下,我们可以将整个电商项目拆分为:电商交易系统、后台管理系统、CMS管理系统等。
但是分布式架构也存在很大的问题,像在电商项目下有电商交易系统和后台管理系统中都用用户管理,就需要写两次同样的业务,代码会过于重复,很显著也不是我们想要的效果,因此就演变出来SOA框架
我们将系统演变为分布式架构之后,当业务越来越多,重复编写的业务代码就会越来越多。此时,我们需要将重复的代码抽象出来,形成统一的服务供其他系统或者业务模块来进行调用。此时,系统就会演变为SOA架构。
在SOA架构中,我们会将系统整体拆分为服务层和表现层。服务层封装了具体的业务逻辑供表现层调用,表现层则负责处理与页面的交互操作。
当部署的服务越来越多,就会出现服务集群地址硬编码的问题,此时,我们就需要增加一个
注册中心来解决各个服务之间的注册与发现。(我用的是zookeeper注册中心)
听着SOA框架就很完美,但是呢还是有不足的地方,存在的问题:
服务提供方与调用方接口耦合度较高
抽取服务的粒度较大
通俗的讲就是:一个电商项目分成多个系统,系统和系统之间有的业务需要调用同一个服务,同样就会引发一个问题,如果其中一个服务挂了,那么整个项目也会挂掉
随着业务的发展,我们在SOA架构的基础上进一步扩展,将其彻底拆分为一个个小的可以独立部署的微服务。
微服务架构特征:
Spring Cloud是一系列框架的有序集合如服务发现注册、配置中心、消息总线、负载均衡、熔断器、数据监控等。
SpringCloud是一套微服务开发的全家桶;Spring没有重复造轮子,只是基于springboot将其他公司(Netflix)的服务框架组合起来
通俗的说就是Springboot整合了Netflix众多组件形成了SpringCloud!
因为在2020年Netflix众多组件停止维护(闭源了),所以急需其他的一些替代产品,也就是spring cloud alibaba,目前正处于蓬勃发展的态式,马老师左手双十一,右手阿里开源组件,不仅占据了程序员的购物车,还要攻占大家的开发工具 。
Spring Cloud Alibaba 就是 Springboot加上了alibaba开发的众多组件整合取来形成的Spring Cloud Alibaba
Spring Cloud Alibaba Version | Spring Cloud Version | Spring Boot Version |
---|---|---|
2021.0.1.0 | Spring Cloud 2021.0.1 | 2.6.3 |
2.2.7.RELEASE | Spring Cloud Hoxton.SR12 | 2.3.12.RELEASE |
2021.1 | Spring Cloud 2020.0.1 | 2.4.2 |
2.2.6.RELEASE | Spring Cloud Hoxton.SR9 | 2.3.2.RELEASE |
2.1.4.RELEASE | Spring Cloud Greenwich.SR6 | 2.1.13.RELEASE |
2.2.1.RELEASE | Spring Cloud Hoxton.SR3 | 2.2.5.RELEASE |
2.2.0.RELEASE | Spring Cloud Hoxton.RELEASE | 2.2.X.RELEASE |
2.1.2.RELEASE | Spring Cloud Greenwich | 2.1.X.RELEASE |
2.0.4.RELEASE(停止维护,建议升级) | Spring Cloud Finchley | 2.0.X.RELEASE |
1.5.1.RELEASE(停止维护,建议升级) | Spring Cloud Edgware | 1.5.X.RELEASE |
前面四个字母分别表示 Naming 和 Configuration 的前两个字母, 最后一个s 为 Service
Nacos 是阿里巴巴的新开源项目,其核心定位是 “一个更易于帮助构建云原生应用的集注册中心与配置中心于一体的管理平台”。
下载地址:https://github.com/alibaba/nacos/tags
解压安装包:
[root@localhost ~]# cd /usr/upload [root@localhost upload]# tar -zxvf nacos-server-1.4.1.tar.gz -C /usr/local
启动:
[root@localhost local]# cd nacos/bin/ [root@localhost bin]# ./startup.sh -m standalone #非集群模式启动 ... ... nacos is starting with standalone nacos is starting,you can check the /usr/java/nacos/logs/start.out
关闭:
[root@localhost bin]# ./shutdown.sh The nacosServer(3543) is running... Send shutdown request to nacosServer(3543) OK [root@localhost bin]
浏览器访问:http://192.168.209.129:8848/nacos,默认用户名/密码为: nacos/nacos
注册中心就是用于服务提供者注册服务、服务调用者从中拉取服务列表然后采用负载均衡策略(如Ribbon)从列表中选出一个服务,从而完成请求调用。
注册中心主要有三部分组成:
Nacos-Server:注册中心
提供服务的注册和发现。
Nacos-Provider:服务提供方
把自身的服务实例注册到 Nacos Server 中
Nacos-Consumer:服务调用方
通过 Nacos Server 获取服务列表,消费服务。
①地址硬编码
②不能负载均衡
创建一个项目:springclou_parent
项目结构:
springcloud_common:存放公共的实体类
nacos_provider: 是服务的提供者
nacos_consumer:是服务的消费者也就调用者
4.1、springcloud_parent,父工程pom.xml
~指定项目的编码和JDK版本
UTF-8
UTF-8
1.8
1.8
org.springframework.boot
spring-boot-dependencies
2.3.2.RELEASE
pom
import
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR9
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.2.6.RELEASE
pom
import
4.2 springcloud_common:存放公共的实体类
4.2.1 pom.xml
springcloud_parent
com.bjpowernode
1.0-SNAPSHOT
4.0.0
springcloud_common
4.2.2 pojo 实体类
public class User {
private Integer id;
private String name;
private Integer age;
public User() {
}
public User(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
4.3 nacos_provider: 是服务的提供者
org.springframework.boot
spring-boot-starter-web
com.bjpowernode
springcloud_common
1.0-SNAPSHOT
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
application.yml
server:
port: 9090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.209.129:8848 #nacos服务的地址
application:
name: nacos-provider #向注册中心注册的名字
启动类
@SpringBootApplication
@EnableDiscoveryClient//向注册中心注册该服务,并可以获取其他服务的调用地址
public class NacosProviderApp {
public static void main(String[] args) {
SpringApplication.run(NacosProviderApp.class,args);
}
}
4.2 nacos_consumer:是服务的消费者也就调用者
4.2.1 pom.xml 依赖关系
org.springframework.boot
spring-boot-starter-web
com.bjpowernode
springcloud_common
1.0-SNAPSHOT
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
application.yml
server:
port: 80
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.209.129:8848 #nacos服务的地址
application:
name: nacos-consumer #向注册中心注册的名字
@SpringBootApplication
@EnableDiscoveryClient//向注册中心注册该服务,并可以获取其他服务的调用地址
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class);
}
}
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value="/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//获取nacos中注册的所有服务信息
List serviceList = discoveryClient.getServices();
for (String service : serviceList) {
System.out.println(service);
}
//获取nacos中注册的指定服务信息
ServiceInstance instance = discoveryClient.getInstances("nacos-provider").get(0);
//路径
String url = "http://"+ serviceInstance.getHost()+":"+ serviceInstance.getPort()+"/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
测试
微服务架构下关于配置文件的一些问题 :
基于上面这些问题,我们就需要配置中心的加入来解决这些问题,配置中心的思路是:
首先把项目中各种配置全部都放到一个集中的地方进行统一管理。
当各个服务需要获取配置的时候,就来配置中心的接口拉取自己的配置。
当配置中心中的各种参数有更新的时候,也能通知到各个服务实时的过来同步最新的信息,使之动态更新。
5.2.创建nacos_config :
5.2.1 pom.xml依赖:
org.springframework.boot
spring-boot-starter-web
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
注意:
客户端配置文件的名称必须为bootstrap.yml
bootstrap/ application 的应用场景:
bootstrap.yml
比 applicaton.yml
优先加载,应用于系统级别参数配置,一般不会变动;
application.yml
应用于SpringBoot项目的自动化配置;
spring:
cloud:
nacos:
config:
server-addr: 192.168.204.129:8848
file-extension: yaml #后缀名,只支持 properties 和 yaml 类型
prefix: nacos-config #文件名,如果没有配置则默认为 注册到注册中心的服务名
启动类:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient //该服务注册到nacos服务中心,并发现其他服务的地址
public class NacosConfigApp {
public static void main(String[] args) {
SpringApplication.run(NacosConfigApp.class,args);
}
}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope //重新从BeanFactory获取一个新的实例(该实例使用新的配置)
public class ConfigController {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.type}")
private String type;
@GetMapping("/config/info")
public String getConfigInfo() {
System.out.println(this);
String configInfo = driverClassName+"
"+url+"
"+username+"
"
+password+"
"+type;
return configInfo;
}
}
5.3.1 Nacos 中,dataId(配置文件的命名的规则) 的完整格式如下:
${spring.cloud.nacos.config.prefix}.${spring.cloud.nacos.config.file-extension}
spring.cloud.nacos.config.prefix:默认是当前服务的服务名称
spring.cloud.nacos.config.file-extension:配置文件的格式(后缀),目前只支持yaml和properties
步骤:
Namespace Group DataId介绍:
Namespace: 代表不同的环境的配置隔离, 如: 开发、测试, 生产等
Group: 可以代表某个项目, 如XX医疗项目, XX电商项目
DataId: 每个项目下往往有若干个工程, 每个配置集(DataId)是一个工程的主配置文件
获取配置集需要指定:
nacos服务地址,必须指定
namespace,如不指定默认public
group,如不指定默认 DEFAULT_GROUP
dataId,必须指定
建立好所有namespace后,在配置管理与服务管理模块下所有页面,都会包含用于切换namespace的选项卡
读取配置文件
spring:
cloud:
nacos:
config:
server-addr: 192.168.204.129:8848
file-extension: yaml
prefix: nacos-config
namespace: dev #开发环境
读取配置类
spring:
cloud:
nacos:
config:
server-addr: 192.168.204.129:8848
file-extension: yaml
prefix: nacos-config
namespace: a66ca122-fb24-46ba-bde0-58508c2d6689
group: NACOS_GROUP #nacos项目
测试: