SpringCloud和Nacos的基础知识和使用

news2024/12/15 17:57:50

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?spm=1001.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依赖:

在这里插入图片描述

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.23</version>
</dependency>
<dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>3.5.11</version>
</dependency>
<dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>1.3.2</version>
</dependency>

​ 6.添加SpringCloud依赖库,后续子模块使用的时候就不需要再指定版本了

在这里插入图片描述

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-dependencies</artifactId>
     <version>${spring-cloud.version}</version>
     <type>pom</type>
     <scope>import</scope>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.9.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
2.2.1.3 创建子项目
	1.在父级项目上新建模块(user_client),并修改子项目的pom文件引入父项目的坐标

在这里插入图片描述

在这里插入图片描述

​ 2.为了将子项目作为Nacos的client,需要引入如下依赖:

 <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.0.1.0</version>
</dependency>

在这里插入图片描述

​ 3.编写application.yml文件

在这里插入图片描述

#服务端口,随便起
server:
  port: 8082
#服务名称
spring:
  application:
    name: userclient
  datasource:
    url: jdbc:mysql://localhost:3306/user
    username: root
    password: cmq123
    driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    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 {
    @Autowired
    private UserMapper userMapper;

    public User findById(Integer id){
        System.out.println("UserService: "+ id);
        return userMapper.find(id);
    }
}

UserController代码如下:

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private 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;
    }

    @Override
    public 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;
    }

    @Override
    public 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 {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private 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 {
    @Autowired
    private 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
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

​ 为了将我们实体类和数据库中的字段对应,我们需要在application.yml文件中开启驼峰命名:

mybatis:
  type-aliases-package: com.ayanokouji.ordersclient.pojo.Order
  configuration:
    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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2260055.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手机实时提取SIM卡打电话的信令声音--社会价值(一、方案解决了什么问题)

手机实时提取SIM卡打电话的信令声音 --社会价值(一、方案解决了什么问题) 一、前言 这段时间&#xff0c;我们在技术范围之外陷入了一个自证或者说下定义的怪圈&#xff0c;即要怎么样去介绍或者描述&#xff1a;我们是一个什么样的产品。它在当前这个世界上&#xff0c;处于…

使用navicat新旧版本,连接PostgreSQL高版本报错问题图文解决办法

使用navicat新旧版本&#xff0c;连接PostgreSQL高版本报错问题图文解决办法 一、问题现象&#xff1a;二、出现原因三、解决方法&#xff1a;1、升级Navicat版本&#xff1a;2、使用低版本的postgreSQL&#xff1a;3、修改Navicat的dll二进制文件&#xff1a;navicat版本15nav…

12.1【JAVA EXP4】next项目

next项目构建问题 详解一下这个页面 什么是Node选项&#xff1f; Node选项是指在运行Node.js应用程序时可以传递给Node.js进程的一系列命令行参数。这些选项可以让开发者控制Node.js的行为&#xff0c;例如设置内存限制、启用或禁用某些功能、指定调试端口等 --inspect 和 --i…

【操作系统】实验九:设备驱动程序

实验9 设备驱动程序 在钻研Linux内核的人当中&#xff0c;大多数人都是在写设备驱动程序。尽管由于设备的特殊性&#xff0c;使得每个驱动程序都不一样。但是编写设备驱动程序的许多原则和基本技巧都是一样的&#xff0c;甚至Windows下的设备驱动程序从原理上讲也与之相通。在…

腾讯云COS跨域访问CORS配置

腾讯云COS跨域访问CORS配置方法如下&#xff0c;参考以下截图&#xff1a; 参考文章&#xff1a; 跨域及CORS-Nginx配置CORS

从EXCEL表格到WEB TABLE的实践

前言 EXCEL管理数据 Bootstrap Bootstrap 是一个流行的开源前端框架&#xff0c;它由 Twitter 的员工开发&#xff0c;用于快速开发响应式和移动设备优先的网页和应用程序。 jQuery jQuery 是一个快速、小巧且功能丰富的 JavaScript 库。它简化了 HTML 文档的遍历、事件处理…

python中向量指的是什么意思

一、向量是什么 在数学中&#xff0c;向量&#xff08;也称为欧几里得向量、几何向量、矢量&#xff09;&#xff0c;指具有大小&#xff08;magnitude&#xff09;和方向的量。它可以形象化地表示为带箭头的线段。箭头所指&#xff1a;代表向量的方向&#xff1b;线段长度&am…

高数 导数

文章目录 一&#xff0c;导数的知识点 二&#xff0c;单侧导数 三&#xff0c;可导和连续的关系 四&#xff0c;复合函数求导 五&#xff0c;参数方程求导 六&#xff0c;高阶导数求导 七&#xff0c;隐函数求导 八&#xff0c;微分基础 一&#xff0c;导数常用的知识点 …

基于Spring Boot的同城宠物照看系统的设计与实现

一、摘要 在快节奏的现代生活中&#xff0c;宠物已成为许多家庭不可或缺的一部分。然而&#xff0c;宠物照看服务的需求也随之增长。为了满足这一需求&#xff0c;我们设计并实现了一款同城宠物照看系统&#xff0c;该系统利用Java技术和MySQL数据库&#xff0c;为用户提供一个…

光伏逆变器负载的维护和保养方法有哪些?

光伏逆变器是光伏发电系统中的关键设备&#xff0c;它将太阳能电池板产生的直流电转换为交流电&#xff0c;为家庭和工业用电提供稳定的电力。为了保证光伏逆变器的正常运行和延长其使用寿命&#xff0c;我们需要对其进行定期的维护和保养。以下是一些建议&#xff1a; 清洁&a…

离开花少6后的周雨彤,还会不会好了

花儿与少年&#xff0c;这档著名的旅行综艺&#xff0c;从丝路季的9.3分&#xff0c;一路狂跌至第六季的3.9分&#xff0c;有人说是因为节目里太过抓马&#xff0c;导致这季分数太低&#xff0c;然而以最强抓马著称的花少2都有7.1分的高分。 花少6难看是真的&#xff0c;导演组…

警惕!手动调整服务器时间可能引发的系统灾难

警惕&#xff01;手动调整服务器时间可能引发的系统灾难 1. 鉴权机制1.1 基于时间戳的签名验证1.2 基于会话的认证机制&#xff08;JWT、TOTP&#xff09; 2. 雪花算法生成 ID 的影响2.1 时间戳回拨导致 ID 冲突2.2 ID 顺序被打乱 3. 日志记录与审计3.1 日志顺序错误3.2 审计日…

群控系统服务端开发模式-应用开发-操作记录功能开发

一、开放路由 在根目录下route文件夹下修改app.php文件&#xff0c;代码如下&#xff1a; // 操作日志Route::get(token/get_list,permission.Token/getList);// 获取操作日志列表Route::post(token/get_all,permission.Token/getAll);// 获取操作日志所有数据Route::post(toke…

无限弹窗?无限重启?

Windows开机自启目录&#xff1a; "%USERPROFILE%\AppData\Roaming\Microsoft\windows\StartMenu\Programs\Startup" 基于这个和 start 命令&#xff0c; shutdown 命令&#xff0c; 编写 bat 病毒程序。 无限弹窗 echo start cmd > hack.txt echo %0 >>…

6.1 初探MapReduce

MapReduce是一种分布式计算框架&#xff0c;用于处理大规模数据集。其核心思想是“分而治之”&#xff0c;通过Map阶段将任务分解为多个简单任务并行处理&#xff0c;然后在Reduce阶段汇总结果。MapReduce编程模型包括Map和Reduce两个阶段&#xff0c;数据来源和结果存储通常在…

Scripted Pipeline语法简单使用

一、JenkinsFile 语法参数 env_tools 环境工具变量的定义设置位置&#xff1a; “Manage Jenkins”-> “Tools” stage(env tools) {node(test){ //定义maven java环境def mvnHome tool MAVEN_HOME_CentOS//引用环境变量&#xff0c;配置PATH变量env.PATH &qu…

前端退出对话框也就是点击右上角的叉,显示灰色界面,已经解决

文章目录 遇到一个前端bug&#xff0c;点击生成邀请码 打开对话框 然后我再点击叉号&#xff0c;退出对话框&#xff0c;虽然退出了对话框&#xff0c;但是显示灰色界面。如下图&#xff1a; 导致界面就会失效&#xff0c;点击任何地方都没有反应。 发现是如下代码的问题&am…

在 Kibana 中为 Vega Sankey 可视化添加过滤功能

作者&#xff1a;来自 Elastic Tim Bosman 及 Miloš Mandić 有兴趣在 Kibana 中为 Vega 可视化添加交互式过滤器吗&#xff1f;了解如何利用 “kibanaAddFilter” 函数轻松创建动态且响应迅速的 Sankey 可视化。 在这篇博客中&#xff0c;我们将了解如何启用 Vega Sankey 可视…

【实验】【H3CNE邓方鸣】交换机端口安全实验+2024.12.11

实验来源&#xff1a;邓方鸣交换机端口安全实验 软件下载&#xff1a; 华三虚拟实验室: 华三虚拟实验室下载 wireshark&#xff1a;wireshark SecureCRT v8.7 版本: CRT下载分享与破解 文章目录 dot1x 开启802.1X身份验证 开启802.1X身份验证&#xff0c;需要在系统视图和接口视…

qt 封装 调用 dll

这个目录下 &#xff0c;第一个收藏的这个 &#xff0c;可以用&#xff0c; 但是有几个地方要注意 第一.需要将dll的头文件添加到qt的文件夹里面 第二&#xff0c;需要在pro文件里面添加动态库路径 第三&#xff0c;如果调用dll失败&#xff0c;那么大概需要将dll文件放在e…