微服务(SpringCloud)

2023-11-04

1、什么是微服务?

将一个大项目中各个业务代码进行拆分,拆分成多个互不相干小项目,每个项目完成自己特有的功能,而且可以通过调用别的项目完成整体功能。

2. SpringCloud

是由Spring提供的一套能够快速搭建微服务框架程序的框架集,也被叫做Spring全家桶,广义上指Spring的所有产品

3 、微服务的实现
  • Netflflix奈非实现
  1. Eureka
  2. Hystrix
  3. Hystrix Dashboard
  4. Hystrix Turbine
  5. Ribbon
  6. Feign
  7. Zuul
  • SpringCloud Alibaba实现
  1. nacos
  2. dubbo
  3. seata
  4. sentinel
  5. gateway
  6. elasticsearch

4nacos

  • 注册中心、配置中心
  • nacos心跳机制
  1. 服务每5秒会与nacos进行一次交互,如果连续3(15)未收到交互信息,nacos就将此服务
         标记为异常服务
     2.如果连续6次(30秒)没有和 nacos 进行交互, nacos 将从注册列表中删除此服务
  • nacos使用
  1. 添加依赖
<!-- Nacos注册依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacosdiscovery</artifactId>
</dependency>

     2.添加配置信息

spring:
application:
name: nacos-cart # 定义当前服务名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 指定正在运行的Nacos服务器的位置
ephemeral: false #默认是true(临时) false(永久)

    3.nacos启动命令

startup.cmd -m standalone

5、远程过程调用RPC

RPC 实现方式: dubbo,RestTemplate
  • RestTemplate
  1. 创建对象交个spring管理
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}

    2.直接远程调用

//在service层调用远程方法
@Autowired
private RestTemplate restTemplate;
public User findByUserById(int id){
String url = "http://nacos-cart/user/findUser?id={1}";
User user = restTemplate.getForObject(url,User.class,id);
return user;
}
  • dubbo
  1. 添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>cn.tedu</groupId>
<artifactId>csmall-cart-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

    2.添加配置

dubbo:
protocol:
port: -1
name: dubbo
registry:
address: nacos://localhost:8848
consumer:
check: false

    3.标记服务接口

//被调用方法的实现类前面加(生产者)
@DubboService
//在被调用的服务的主启动类前加
@EnableDubbo
//在调动远程服务的业务层添加被调用的接口
@DubboReference
private ICartService cartService;

6、负载均衡

将请求平均、合理的分配到每一个服务器,尽量让请求去相对空闲的服务器
负载均衡策略:
  • random loadbalance: 随机分配
  • round Robin loadbalance: 权重平均分配
  • leastactive loadbalance: 活跃度自动感知
  • consistanthash loadbalance:一致性hash算法(使用的少)

7Seata 分布式事务解决方案

分布式事务解决方案,在微服务架构下提供高性能和简单易用的分布式服务
Seata提供4种事务模式
  • AT
  • TCC
  • SAGA
  • XA

Seata的构成部分

  • TC: 事务协调器
  • TM: 事务管理器
  • RM: 资源管理器

Seata使用

添加依赖( 生产者添加 3 个,消费者添加第一个就可以了)
<!-- Seata和SpringBoot整合依赖 -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</dependency>
<!-- Seata 完成分布式事务的两个相关依赖(Seata会自动使用其中的资源) -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
添加配置 ( 生产者和消费者都要添加 )
seata:
# 定义事务的分组,一般是以项目为单位的,不同项目用它来区分
tx-service-group: csmall_group
service:
vgroup-mapping:
# 设置csmall_group分组使用默认(default)的seata配置
csmall_group: default
grouplist:
# 设置seata的ip和端口号位置
default: localhost:8091
添加一个注解 ( 在事务开始的方法上 )
@GlobalTransactional
Seata 启动命令
seata-server.bat -h 127.0.0.1 -m file

8Sentinel

流量控制,降级,熔断,系统负载保护,保证在设计的请求数内的请求能够稳定的完成处理。
  • Sentinel使用
  1. 添加依赖
<!-- Sentinel 整合SpringCloud依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

     2.添加配置

spring:
cloud:
sentinel:
transport:
# 配置sentinel提供的仪表台服务器的位置
dashboard: localhost:8080
# 执行限流的端口号,每个项目必须设置不同的端口号,例如cart模块要限流就可以设
置为8722
port: 8721
    3.启动服务
windows直接双击: start-sentinel.bat
  • 限流方式
  1. 直接限流
  2. 关联限流
  3. 链路限流

9、SpringGateway

程序中的网关就是当前微服务项目对外界开放的统一入口
所有外界的请求都需要先经过网关才能访问到我们的程序
提供了统一入口之后 , 方便对所有请求进行统一的检查和管理
  • 添加依赖 
<dependencies>
<!-- SpringGateway的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Nacos依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacosdiscovery</artifactId>
</dependency>
<!-- 网关负载均衡依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
  • 添加配置

server:
port: 9000
spring:
application:
name: gateway
cloud:
nacos:
discovery:
# 网关也是微服务项目的一部分,所以也要注册到Nacos
server-addr: localhost:8848
gateway:
# discovery:
# locator:
# # 开启网关动态路由的配置
# # 默认的路由规则:在网关端口号后,先编写要路由到的目标服务器
# # 注册到Nacos的名称,再编写要访问的具体路径
# # 例如 localhost:9001/bj/show -> localhost:9000/beijing/bj/show
# enabled: true
# routes就是路由的意思,下面的内容就是配置路由,它是一个数组类型的属性
routes:
- id: gateway-shanghai
uri: lb://shanghai
predicates:
- Path=/sh/**
# 数组类型属性赋值时,每个数组元素都要以"-"开头,一个"-"之后的所有内容,都是这个元素
包含的值
# id表示当前路由的名称,和之前出现过的任何名字没有关联,唯一的要求就是不能和之后出现
的路由id重复
- id: gateway-beijing
# uri配置路由的目标服务器,beijing是服务器注册到nacos的名称
# lb就是LoadBalance的缩写
uri: lb://beijing
# predicates是断言的意思,指满足某些条件的之后执行某些操作
predicates:
# predicates属性也是数组类型,赋值要以"-"开头
# 这个断言的含义就是如果访问网关项目的路径以/bj/开头,路由访问beijing服务器
# ↓ P要大写 **是通配任何路径
- Path=/bj/**

10Elasticsearch

  • 添加依赖
<!-- spring data elasticsearch 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  • 添加配置
# 配置ES所在的ip地址和端口号
spring.elasticsearch.rest.uris=http://localhost:9200
# 设置日志门槛,用于显示ES运行信息
logging.level.cn.tedu.search=debug
# SpringDataElasticsearch框架中有一个专门的类来输出运行信息,也要设置为debug
logging.level.org.elasticsearch.client.RestClient=debug
  • 编写接口代码
// Repository是Spring家族框架对持久层的命名
@Repository
public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
// ItemRepository接口要继承SpringData提供的ElasticsearchRepository父接口
// 一旦继承,当前接口就可以编写连接ES进行操作的代码了,继承了这个父接口之后
// 会自动生成对Item数据的基本增删改查方法,无需我们自己编写
// ElasticsearchRepository<[关联的实体类的名称],[实体类主键的类型]>
}
  • 编写测试代码
// 必须添加下面的注解,否则无法运行
@SpringBootTest
public class SpringDataTest {
@Autowired
private ItemRepository itemRepository;
// 执行单增
@Test
void addOne(){
// 实例化一个item对象并赋值
Item item=new Item()
.setId(1L)
.setTitle("罗技激光无线游戏鼠标")
.setCategory("鼠标")
.setBrand("罗技")
.setPrice(188.0)
.setImgPath("/1.jpg");
// 利用SpringData提供的新增方法,完成Item新增到ES
itemRepository.save(item);
System.out.println("ok");
}
// 单查
@Test
void getOne(){
// SpringDataElasticsearch提供了按id查询数据的方法
// Optional是一个容器,但是只能存放一个元素,Springdata返回包含查询结果的
Optional对象
// 可以将Optional理解为一个只能保存一个元素的List
Optional<Item> optional=itemRepository.findById(1L);
Item item=optional.get();
System.out.println(item);
}
// 批量增
@Test
void addList(){
// 实例化一个List对象,用于保存要新增到ES中对象
List<Item> list=new ArrayList<>();
list.add(new Item(2L,"罗技激光有线办公鼠标","鼠标",
"罗技",98.0,"/2.jpg"));
list.add(new Item(3L,"雷蛇机械无线游戏键盘","键盘",
"雷蛇",278.0,"/3.jpg"));
list.add(new Item(4L,"微软有线静音办公鼠标","鼠标",
"微软",197.0,"/4.jpg"));
list.add(new Item(5L,"罗技机械有线背光键盘","键盘",
"罗技",226.0,"/5.jpg"));
itemRepository.saveAll(list);
System.out.println("OK list");
}
// 全查
@Test
void getAll(){
// SpringData提供的全查ES中对应实体类的所有数据的方法
Iterable<Item> items=itemRepository.findAll();
for(Item item : items){
System.out.println(item);
}
System.out.println("--------------------------------");
items.forEach(item -> System.out.println(item));
}
}
  • SpringData自定义查询
//在接口中添加方法
// SpringData实现自定义查询
// 我们要编写遵循SpringData给定格式的方法名
// SpringData会根据我们编写的方法名自动完成数据操作
// query(查询):表示当前方法是一个查询方法,类似sql语句中的select
// Item/Items:确定要查询哪一个实体类,不带s的是单个对象,带s是集合
// By(通过/根据):标识开始设置查询条件,类似sql语句中的where
// Title:要查询的字段,可以根据查询条件修改为Item中的任何字段
// Matches:执行查询的操作,Matches表示字符串的匹配,而且这个匹配是支持分词的,类似sql语句
的like
//但条件查询
Iterable<Item> queryItemsByTitleMatches(String title);
// 多条件查询
// 多个条件之间要使用逻辑运算符and或or来分隔,表示多个条件间的逻辑关系
// 我们如果要查询title包含某个关键字的同时指定品牌的查询
// 多个参数时,SpringData会按照参数声明的顺序向需要参数的位置赋值,和参数名无关
Iterable<Item> queryItemsByTitleMatchesAndBrandMatches(
String title,String brand);
// 排序查询
Iterable<Item> queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
String title,String brand);
// 分页查询
// 返回值类型修改为Page类型,这个类型中包含了查询到的当前页数据和本次查询的相关分页信息
// 分页信息指:当前页码,总页数,总条数,每页条数,是否有上一页,是否有下一页等
// 方法参数要添加Pageable,在所有的参数后再添加一个新的参数类型 Pageable
Page<Item> queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
String title, String brand, Pageable pageable);
//------------------------------------------------------------------------
//测试类添加方法
// 单条件查询
@Test
void queryOne(){
// 查询ES中items索引里,title字段包含"游戏"分词的数据
Iterable<Item> items=itemRepository.queryItemsByTitleMatches("游戏");
items.forEach(item -> System.out.println(item));
}
// 多条件查询
@Test
void queryTwo(){
// 查询ES中items索引里,title字段包含"游戏"并且品牌是"罗技"的数据
Iterable<Item> items=itemRepository
.queryItemsByTitleMatchesAndBrandMatches("游戏","罗技");
items.forEach(item -> System.out.println(item));
}
// 排序查询
@Test
void queryOrder(){
Iterable<Item> items=itemRepository
.queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
"游戏","罗技");
items.forEach(item -> System.out.println(item));
}
// 分页查询
@Test
void queryPage(){
int page=2; //要查询的页码
int pageSize=2; //每页的数据条数
Page<Item> pages=itemRepository
.queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
"游戏","罗技", PageRequest.of(page-1,pageSize));
pages.forEach(item -> System.out.println(item));
// pages对象的分页信息输出
System.out.println("总页数:"+pages.getTotalPages());
System.out.println("总条数:"+pages.getTotalElements());
System.out.println("当前页码:"+(pages.getNumber()+1));
System.out.println("每页条数:"+pages.getSize());
System.out.println("是否为首页:"+pages.isFirst());
System.out.println("是否为末页:"+pages.isLast());
}
  • ES查询语法:
### 三个#是注释,也是分隔符,http文件要求每个请求必须以分隔符开始,否则会报错
GET http://localhost:9200
### 测试ES的分词功能,运行请求,查看分词结果
POST http://localhost:9200/_analyze
Content-Type: application/json
{
"text": "周杰伦出新专辑了",
"analyzer": "ik_max_word"
}
### 创建 index
PUT http://localhost:9200/questions
### 删除一个Index
DELETE http://localhost:9200/questions
### 设置index中的文档属性采用ik分词
POST http://localhost:9200/questions/_mapping
Content-Type: application/json
{
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
### questions 中添加文档
POST http://localhost:9200/questions/_create/1
Content-Type: application/json
{
"id":1,
"title":"Java基本数据类型有哪些",
"content":"面时候为啥要问基本类型这么简单问题呀,我们要如何回答呢?"
}
### questions 中添加文档
POST http://localhost:9200/questions/_create/2
Content-Type: application/json
{
"id":2,
"title":"int类型的范围",
"content":"为啥要了解int类型的范围呢?"
}
### questions 中添加文档
POST http://localhost:9200/questions/_create/3
Content-Type: application/json
{
"id":3,
"title":"常用集合类有哪些",
"content":"为啥企业经常问集合呀?该如何回复呢"
}
### questions 中添加文档
POST http://localhost:9200/questions/_create/4
Content-Type: application/json
{
"id":4,
"title":"线程的run方法和start方法有啥区别",
"content":"run方法可以执行线程的计算过程, start也可以执行线程的计算过程,用途一样
么?"
}
### 更新questions索引中的文档
POST http://localhost:9200/questions/_doc/4/_update
Content-Type: application/json
{
"doc": {
"title": "Java线程的run方法和start方法有啥区别"
}
}
### 删除questions中的一个文档
DELETE http://localhost:9200/questions/_doc/2
### 查询数据
GET http://localhost:9200/questions/_doc/4
### 搜索 ES
POST http://localhost:9200/questions/_search
Content-Type: application/json
{
"query": { "match": {"title": "java类型" } }
}
### 多字段搜索
POST http://localhost:9200/questions/_search
Content-Type: application/json
{
"query": {
"bool": {
"should": [
{ "match": { "title": "java类型" }},
{ "match": { "content": "java类型"}}
]
}
}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微服务(SpringCloud) 的相关文章

随机推荐

  • 线程状态是五种对?还是六种对?

    五种 线程在一定条件下 状态会发生变化 线程一共有以下几种状态 1 新建状态 New 新创建了一个线程对象 2 就绪状态 Runnable 线程对象创建后 其他线程调用了该对象的start 方法 该状态的线程位于 可运行线程池 中 变得可运
  • 推荐系统系列——推荐系统简介

    目录 演化关系图 推荐系统简介 什么是推荐系统 为什么需要推荐系统 如何构建推荐系统 推荐系统的步骤 常用评测指标 召回与排序 召回层与排序层的特点 多路召回 使用Embedding做召回 A B测试 为什么需要A B测试 A B测试的流程
  • 基于神经回路的靶向治疗的未来

    以靶向大脑回路为原则的治疗方法 随着诸如经颅磁刺激 TMS 深部脑刺激 DBS 和聚焦超声 FUS 等脑刺激治疗的发展 逐渐引起了广泛关注 这些技术可以有效治疗不同的神经精神疾病 但治疗特定疾病取决于选择合适的治疗目标 在这里 我们提出了一
  • 删除type报ORA-02303错误

    drop type result type 时 报错ORA 02303 无法使用类型或表的相关性来删除或取代一个类型 drop type result type array 时报错 对象不存在 CREATE OR REPLACE TYPE
  • 练习敲代码速度

    2023年9月18日 周一晚上 今晚不想学习 但又不想玩游戏 于是找了一些练习敲代码的网站来玩玩 顺便练习一下敲代码的速度 目录 参考资料 个人推荐 第一个 第二个 第三个 参考资料 电脑打字慢 有哪些比较好的练打字软件 知乎 https
  • C#——Lambda 表达式

    C Lambda 表达式 Lambda 表达式 是采用以下任意一种形式的表达式 表达式 lambda 表达式为其主体 input parameters gt expression 语句 lambda 语句块作为其主体 input param
  • 分布式相关论文

    想从事分布式系统 计算 hadoop等方面 需要哪些基础 推荐哪些书籍 转自知乎 作者 廖君 链接 https www zhihu com question 19868791 answer 88873783 来源 知乎 分布式系统 Dist
  • 线性代数学习之正交性,标准正交矩阵和投影

    正交基和标准正交基 前言 经过上一次线性代数学习之向量空间 维度 和四大子空间的学习 对于空间的概念已经有了非常深刻的认识了 而描述空间很重要的方式除了维度以外 那就是空间的基了 而如小标题所示就是跟空间的基相关 所以先来回忆一下空间基的相
  • autojs获取最近创建的媒体文件,获取本机音频视频图片文件脚本源码,翻译自java

    说明 本文提供的代码仅供参考 不建议用于生产环境 可能有些地方在最新版本的Auto js上面需要做修改 才能运行 Auto js简介 Auto js是利用安卓系统的 辅助功能 实现类似于按键精灵一样 可以通过代码模拟一系列界面动作的辅助工作
  • 宋人千首绝句【全十卷】

    千首宋人绝句 是清代严长明编辑的书籍 全书共十卷 分七言 五言 六言三部分 其中七言七卷 五言两卷 六言一卷 且按帝王 后妃 宫掖 宗室 降王 宋臣 闺媛等分类 收录有王安石 苏轼 黄庭坚 秦观 陆游 杨万里 范成大等著名诗人的六言绝句 编
  • 看了一次strongswan ipsec的设置.

    看了一次strongswan ipsec的设置 这次的设置要求是 Linux 中 strongwans与hillstone防火墙 stoneOS 建立ipsec连接 network network进行通信 要求Linux可以同时与多台防火墙
  • 从2018年以太坊统计数据看区块链发展趋势

    今年6月 我们发布了 以太坊网络状态 重点介绍了整个网络的一些关键数据和统计数据 六个月后 即将在2018年结束时 我们处于长期 加密货币冬天 的尾声 2017年末至今的市场波动已经引起了区块链行业的普遍关注 然而 仔细研究这些数字可以发现
  • Python实现根据磁盘剩余空间对磁盘多次写入和擦除

    实现根据磁盘剩余容量 对剩余容量 预留了1GB 进行多次的写入和删除数据 次数为变量counts 每次写入1GB的数据 即变量data 多次操作 以实现上述功能 通过更改taskTimes变量可以多次写入和删除 from datetime
  • 基于STM32的智能电子秤设计

    硬件设计 本设计是一款基于STM32单片机的电子秤系统 随着科学技术的不断发展 传统的机械秤逐渐被电子秤所取代 相比于计量不精确 费时费力的机械秤 电子秤采用在方便快捷的同时 又保证了结果的准确性 本次设计采用STM32单片机作为处理器 控
  • 03智慧安防

    一张图读懂一个产业之智慧安防 自2015年起 安防行业逐渐引入人工智能技术 智慧安防 一词开始进入大众视野 伴随着政府 平安城市 天网工程 雪亮工程 等项目不断推出 智慧安防快速成为智慧城市应用中落地情况较好 技术与服务相对成熟的领域之一
  • java 实现部门树_Java实现部门模块开发

    一 新增部门接口开发 1 1 DeptParam java 1 2 LevelUtils java 1 4 1 导入 commons lang3 依赖包 1 2 2 实现LevelUtils开发 1 3 在 com yuluomoshang
  • 物联网设备获取北京时间、年月日、星期几,GMT格林威治标准时间转换为北京时间,授时api Fiddler抓包调试

    1 获取北京时间 年月日 授时api 苏宁获取北京时间的api不要太方便 http quan suning com getSysTime do 使用 Fiddler抓包调试 查看HTTP返回报文 双击左侧抓取到的HTTP返回报文 使用 Sy
  • 同步异步BUCK研究

    目录 一 同步时钟 二 异步BUCK电路 1 基本公式推导 2 电感选型计算 三 同步BUCK电路 四 同步异步BUCK电路对比 前言 在硬件设计中 电源模块基本都会接触到 DC DC拓扑电路又是最常见的 所以深入理解DC DC电路至关重要
  • 轻松成为设计高手

    目录 2 Verilog语言基础 2 1 三种描述方法 2 Verilog语言基础 2 1 三种描述方法 1 数据流描述 assign连续赋值语句 2 行为描述 过程赋值语句 always和initial过程块 3 结构化描述 实例化已有的
  • 微服务(SpringCloud)

    1 什么是微服务 将一个大项目中各个业务代码进行拆分 拆分成多个互不相干小项目 每个项目完成自己特有的功能 而且可以通过调用别的项目完成整体功能 2 SpringCloud 是由Spring提供的一套能够快速搭建微服务框架程序的框架集 也被