青海西宁制作网站专业,wordpress设置logo和公司名,犀牛云做网站怎么这么贵,网站建设添加展示栏1.什么是SpringCloud
什么是微服务#xff1f;
假如我们需要搭建一个网上购物系统#xff0c;那么我们需要哪些功能呢#xff1f;商品中心、订单中心和客户中心等。
当业务功能较少时#xff0c;我们可以把这些功能塞到一个SpringBoot项目中来进行管理。但是随…1.什么是SpringCloud
什么是微服务
假如我们需要搭建一个网上购物系统那么我们需要哪些功能呢商品中心、订单中心和客户中心等。
当业务功能较少时我们可以把这些功能塞到一个SpringBoot项目中来进行管理。但是随着业务越来越多每个模块需要实现的功能越来越多时每个模块需要的开发人员就越来越多这时如果再是一个项目就不太合适了耦合度太高并且开发人员对同一个项目进行操作容易出现问题。这就需要将原先的系统进行拆分可以按照功能模块拆分成多个服务这就引出了另一个问题服务之间如何完成通信。
在实际的业务场景中每个功能模块不可能是完全分离的例如订单中心展示订单时可能需要获取商品的信息和客户的信息这就需要调用商品中心模块和客户中心模块的接口。SpringCloud就支持我们将原有项目进行拆分分成多个微服务并支持微服务之间的通信。
1.1 SpringCloud简介
SpringCloud由五大组件构成
1.注册中心Euraka国内用的较多的是Nacos负责服务注册和发现。
2.负载均衡Ribbon负责服务实例的选择同一个服务可能部署在多个服务器上。
3.远程调用Feign通过HTTP请求调用其他服务的接口。
4.熔断器Hystrix容错管理工具用于处理分布式系统中的延迟和故障。
5.API网关Zuul用于路由、过滤和负载均衡。 这五大组件的工作流程如下绕不开的八股
1.服务注册只有一个服务注册到注册中心才可能被其他服务发现并调用
2.服务发现即一个服务通过注册中心发现了其他服务
3.负载均衡客户端维护一份从注册中心获取的Provider列表清单根据自己配置的Provider负载均衡选择算法在客户端进行请求的分发
4.服务调用一个服务对另一个服务进行调用
5.隔离、熔断与降级通过Hystrix的线程池去访问服务不同的服务通过不同的线程池实现了不同的服务调度隔离如果服务出现故障通过服务熔断避免服务雪崩的问题 并且通过服务降级保证可以手动实现服务正常功能
6.网关路由如果前端调用后台系统统一从网关进入通过网关转发请求给对应的服务
1.2 Eureka
服务注册中心Eureka server/Nacos server像是整个微服务架构中的大脑服务Eureka client需要注册到Eureka server以供其他服务Eureka client发现如果要使用其他服务的功能也需要通过Eureka server来获得对应服务Eureka client的信息。
Eureka server的主要功能为服务注册表维护和服务健康检查Eureka client的主要功能为服务注册、心跳续约与健康状况查询。是不是觉得很熟悉有点像Redis的哨兵机制
1.3 Ribbon
在实际的生产环境中某些模块访问量较高单个服务器可能无法承载这些访问请求需要将这个微服务同时部署到多台服务器上当有服务请求打到Eureka server上时Eureka server会返回该服务类型对应的所有Eureka client实例。因此客户端会获得多个服务实例Ribbon会选择哪个实例去处理请求选择的方式有多种轮询、随机、权重等主要目的是避免多次请求均打到同一个服务实例上。Ribbon的作用是负载均衡。
Ribbon可以获取Provider清单并且通过IPing实例定期如每10秒向每个Provider实例发送“ping”并且根据Provider是否有响应来判断该Provider实例是否可用。如果该Provider的可用性发生了改变或者Provider清单中的数量和之前的不一致就从注册中心更新或者重新拉取Provider服务实例清单。每次RPC请求到来时由Ribbon的IRule负载均衡策略接口的某个实现类来进行负载均衡。
1.4 Feign
在 Spring Cloud 中使用 Feign可以做到使用 HTTP 请求访问远程服务就像调用本地方法一样的开发者完全感知不到这是在调用远程方法更感知不到在访问 HTTP 请求。Feign 整合了 Ribbon 和 Hystrix具备负载均衡、隔离、熔断与降级功能。
1.5 Zuul
微服务网关是微服务架构中不可或缺的部分它统一解决Provider路由、均衡负载、权限控制等功能。具体可以参考博客https://blog.csdn.net/itigoitie/article/details/125895899?spm1001.2014.3001.5502
1.6 Hystrix
隔离通过Hystrix的线程池去访问服务不同的服务通过不同的线程池实现了不同的服务调度隔离 熔断分布式架构中的熔断器主要用于RPC接口上为接口安装上“保险丝”以防止RPC接口出现拥塞时导致系统压力过大而引起的系统瘫痪当RPC接口流量过大或者目标Provider出现异常时熔断器及时切断故障可以起到自我保护的作用。 降级当服务不可用服务正在等待、链接超时、网络延迟、服务器响应慢等客户端一直等待时调用fallback方法给客户端返回一个错误提示不让客户端继续等待。
2.Nacos
Nacos是阿里的产品它的功能要比Eureka更丰富因此国内更倾向于使用Nacos我们来简单介绍一下Nacos的安装和使用。
2.1 Nacos安装
Nacos官网https://nacos.io/
将压缩包下载到本地并解压避免中文路径进入到bin目录 接着在bin目录下打开cmd输入如下命令来启动Nacos
startup.cmd -m standalone 在浏览器中打开http://192.168.239.1:8848/nacos/index.html 至此Nacos安装就完成了其实还挺简单的接下来我们需要借助Nacos去搭建一个SpringCloud项目下面将介绍如何单机搭建一个SpringCloud项目。
2.2 Nacos简单实践
2.2.1 IDEA搭建SpringCloud项目
2.2.1.1 数据库准备
CREATE TABLE USER (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20) NOT NULL,
phone VARCHAR(15) NOT NULL,
address VARCHAR(50) NOT NULL
);INSERT INTO USER VALUES (1, ayanokoujimonki, 13299075426, 湖北省孝感市)
INSERT INTO USER(NAME, phone, address) VALUES (二哈很六, 18834267011, 江苏省苏州市)
INSERT INTO USER(NAME, phone, address) VALUES (陈大龟, 12481076533, 汉川市榔头村)CREATE TABLE orders (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30) NOT NULL,
price INT NOT NULL,
user_id INT NOT NULL REFERENCES USER(id)
)INSERT INTO orders VALUES (1, 可乐鸡翅, 32, 1);
INSERT INTO orders(NAME, price, user_id) VALUES(冰镇啤酒, 12, 1);
INSERT INTO orders(NAME, price, user_id) VALUES(草莓冰激凌, 8, 2);
INSERT INTO orders(NAME, price, user_id) VALUES(狼牙土豆, 10, 3);2.2.1.2 创建父项目
1.首先创建父项目 2.选择Spring Web依赖 3.等到依赖下载好后删除src目录及mvnw目录正常情况下一般不会直接在父项目下直接编写代码 4.修改pom文件添加packaging标签和SpringCloud版本并修改SpringBoot版本 5.引入mysql和mybatis依赖 dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.23/version
/dependency
dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.11/version
/dependency
dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion1.3.2/version
/dependency 6.添加SpringCloud依赖库后续子模块使用的时候就不需要再指定版本了 dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversion${spring-cloud.version}/versiontypepom/typescopeimport/scope
/dependency
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-dependencies/artifactIdversion2.2.9.RELEASE/versiontypepom/typescopeimport/scope
/dependency2.2.1.3 创建子项目 1.在父级项目上新建模块user_client并修改子项目的pom文件引入父项目的坐标 2.为了将子项目作为Nacos的client需要引入如下依赖 dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactIdversion2021.0.1.0/version
/dependency 3.编写application.yml文件 #服务端口随便起
server:port: 8082
#服务名称
spring:application:name: userclientdatasource:url: jdbc:mysql://localhost:3306/userusername: rootpassword: cmq123driver-class-name: com.mysql.cj.jdbc.Drivercloud:nacos:discovery:server-addr: localhost:8848 4.同样的步骤创建另一个子项目orders_client 2.2.1.5 编写简单的业务代码
其实这时我们启动服务就可以看到服务注册到Nacos上了只不过我们没有编写业务代码因此每个微服务不具备具体功能为了将我们的服务能够被Nacos发现需要在启动类上加上EnableDiscoveryClient注解 浏览器中打开Nacos地址就可以看到我们注册的实例了http://192.168.239.1:8848/nacos/index.html 为了进一步验证服务之间能够通信我们编写简单的业务代码首先是userclient我们编写pojo、controller、service和mapper
其中UserService代码如下
Service
public class UserService {Autowiredprivate UserMapper userMapper;public User findById(Integer id){System.out.println(UserService: id);return userMapper.find(id);}
} UserController代码如下
RestController
RequestMapping(/user)
public class UserController {Autowiredprivate UserService userService;GetMapping(/{id})public User findUserById(PathVariable(id) Integer id){return userService.findById(id);}} UserMapper代码如下
Mapper
public interface UserMapper {Select(select * from user where id#{id})User find(Integer id);
} User代码如下
public class User {private int id;private String name;private String password;private String address;public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;}public String getAddress() {return address;}public void setAddress(String address) {this.address address;}Overridepublic String toString() {return User{ id id , name name \ , password password \ , address address \ };}
} 同理我们继续编写ordersclient的代码项目结构保持相同 User代码于userclient保持一致Order代码如下
public class Order {private int id;private String name;private int price;private int userId;private User user;public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getPrice() {return price;}public void setPrice(int price) {this.price price;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId userId;}public User getUser() {return user;}public void setUser(User user) {this.user user;}Overridepublic String toString() {return Order{ id id , name name \ , price price , userId userId , user user };}
} OrderMapper代码如下
Mapper
public interface OrderMapper {Select(select * from orders where id #{id})Order find(Integer id);
} OrderService代码如下
Service
public class OrderService {Autowiredprivate OrderMapper orderMapper;Autowiredprivate RestTemplate restTemplate;public Order findById(Integer id){Order order orderMapper.find(id);String url http://userclient/user/ order.getUserId();User user restTemplate.getForObject(url, User.class);order.setUser(user);return order;}} OrderController代码如下
RestController
RequestMapping(/order)
public class OrderController {Autowiredprivate OrderService orderService;GetMapping(/{id})public Order findById(PathVariable(id) Integer id){Order byId orderService.findById(id);return byId;}
} 启动类代码如下
EnableDiscoveryClient
SpringBootApplication
public class OrdersClientApplication {public static void main(String[] args) {SpringApplication.run(OrdersClientApplication.class, args);}/**** 定义一个RestTemplate Bean用于发送HTTP请求* return*/BeanLoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}} 为了将我们实体类和数据库中的字段对应我们需要在application.yml文件中开启驼峰命名
mybatis:type-aliases-package: com.ayanokouji.ordersclient.pojo.Orderconfiguration:map-underscore-to-camel-case: true 我们再次启动这两个client并在浏览器输入:localhost:8083/order/1 可以看到这两个服务确实完成了通信虽然不是很优雅。
这就是一个极致简单的SpringCloud项目可以看到代码中我们并未显示地使用负载均衡通信也是使用RestTemplate而不是Feign关于负载均衡和Feign会在后面的博客中介绍如果有时间的话最近公司的活也有点多。
参考博客
Nacos 注册中心下载到搭建详细步骤【微服务】_nacos下载-CSDN博客
IDEA 搭建 SpringCloud 项目【超详细步骤】_idea创建springcloud工程-CSDN博客
Spring Cloud 五大组件_springcloud五大组件-CSDN博客