微服务入门学习笔记(黑马商城)

 课程转跳:SpringCloud微服务Day1-01.微服务课程介绍_哔哩哔哩_bilibili

一、服务拆分

新建一个maven项目将商品服务拆分出去

更改包扫描 

新建一个数据库用于商品服务,同样将表拆分出去

 更改配置文件的服务名和数据库名

 启动多个实例:

 

复制配置修改名称,修改运行端口 

 

启动成功。

 二、服务注册发现(nacos)

创建数据库导入需要的sql文件

centos使用docker安装nacos 

https://hub.docker.com/r/nacos/nacos-server

运行:(前提安装docker)

docker pull nacos/nacos-server

docker images

mkdir -p /mydata/nacos/logs/

mkdir -p /mydata/nacos/init.d/ 

vim /mydata/nacos/init.d/custom.properties

日志映射文件夹和配置
配置文件内容:(配置好自己的mysql信息)

server.contextPath=/nacos
server.servlet.contextPath=/nacos
server.port=8848

spring.datasource.platform=mysql
#配置持久化数据库相关信息 ####################################################
db.num=1
db.url.0=jdbc:mysql://xxx.xxx.xxx.x:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root
##########################################################################

nacos.cmdb.dumpTaskInterval=3600
nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i
nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health/**,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**,/v1/console/server/**
nacos.naming.distro.taskDispatchThreadCount=1
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=true
nacos.naming.expireInstance=true

运行run 

docker run -d -p 8848:8848 -p 9848:9848 -p 9849:9849 --name nacos --privileged=true --restart=always -e JVM_XMS=256m -e JVM_XMX=256m -e MODE=standalone -e PREFER_HOST_MODE=hostname -v /mydata/nacos/logs:/home/nacos/logs -v /mydata/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties --restart=always nacos/nacos-server

 访问地址进入控制台xxx.xxx.xxx.x:8848/nacos

 服务注册:引入依赖

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

配置文件: 

类似的方式启动了cart服务

nacos服务列表:

 openfeign便捷调用服务:

新建模块hm-api引入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

 创建client:

@FeignClient("item-service")
public interface ItemClient {
    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

 返回类:

package com.hmall.api.dto;


import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(description = "商品实体")
public class ItemDTO {
    @ApiModelProperty("商品id")
    private Long id;
    @ApiModelProperty("SKU名称")
    private String name;
    @ApiModelProperty("价格(分)")
    private Integer price;
    @ApiModelProperty("库存数量")
    private Integer stock;
    @ApiModelProperty("商品图片")
    private String image;
    @ApiModelProperty("类目名称")
    private String category;
    @ApiModelProperty("品牌名称")
    private String brand;
    @ApiModelProperty("规格")
    private String spec;
    @ApiModelProperty("销量")
    private Integer sold;
    @ApiModelProperty("评论数")
    private Integer commentCount;
    @ApiModelProperty("是否是推广广告,true/false")
    private Boolean isAD;
    @ApiModelProperty("商品状态 1-正常,2-下架,3-删除")
    private Integer status;
}

 购物车服务引入依赖:

<dependency>
    <groupId>com.heima</groupId>
    <artifactId>hm-api</artifactId>
    <version>1.0.0</version>
</dependency>

启动类添加注解 

@EnableFeignClients(basePackages = "com.hmall.api.client")

 业务调用

private final ItemClient itemClient;    
private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        List<ItemDTO> items = itemClient.queryItemByIds(itemIds);
        // 3.转为 id 到 item的map
        Map<Long, ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity()));
        // 4.写入vo
        for (CartVO v : vos) {
            ItemDTO item = itemMap.get(v.getItemId());
            if (item == null) {
                continue;
            }
            v.setNewPrice(item.getPrice());
            v.setStatus(item.getStatus());
            v.setStock(item.getStock());
        }
    }

三、网关登录校验

创建网关模块,引入springcloud的网关依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

 配置网关转跳路由和过滤器,我的网关端口为8090
uri:lb://nacos中服务的名字
predicates: 服务接口路径
filters: 官方提供的过滤器或自定义过滤器

自定义过滤器有两种GatewayFilterFactory和GlobalFilter,前者可以设置单个服务过滤,也可以设置全局过滤,后者创建完后自动生效全局过滤实现更加简单。

启动,测试

登录校验过滤器实现:将过滤校验所需的配置类和工具类转移到网关

配置jwt和无需过滤的接口路径

@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    private final AuthProperties authProperties;
    private final JwtTool jwtTool;
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        //检查接口是否无需过滤,是则放行
        if(isExclude(request.getPath().toString())){
            return chain.filter(exchange);
        }
        //登录校验
        String token = null;
        List<String> authorization = request.getHeaders().get("authorization");
        if(authorization != null && !authorization.isEmpty()){
            token = authorization.get(0);
        }
        Long userId ;
        try {
             userId = jwtTool.parseToken(token);
        } catch (Exception e) {
            //如果无法生成userId则说明没登录,返回401
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        //如果登录了,则把userId放入请求头发送给接口服务,以便服务需要用户信息
        ServerWebExchange newExchange = exchange.mutate().request(builder -> builder.header("user-info", String.valueOf(userId))).build();
        return chain.filter(newExchange);
    }
    //判断路径是否无需过滤
    private boolean isExclude(String path) {
        List<String> excludePaths = authProperties.getExcludePaths();
        for (String excludePath : excludePaths) {
            if (antPathMatcher.match(excludePath, path)) {
                return true;
            }
        }
        return false;
    }
   
    //过滤器优先级,越小则越高
    @Override
    public int getOrder() {
        return 0;
    }
}

 在common中编写拦截器获取userId

public class UserInfoInterceptor implements HandlerInterceptor {
//请求前将userId存入
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String userId = request.getHeader("user-info");
        if(StrUtil.isNotBlank(userId)){
            UserContext.setUser(Long.parseLong(userId));
        }
        return true;
    }
//出请求后删除userId
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserContext.removeUser();
    }
}

 这样就实现了网关登录校验并且将用户信息传递给其他服务,但其他服务互相调用时还是不会传递用户信息。
 所以我们需要在服务之间发送http请求是带上用户信息的请求头。

借助feign提供的拦截器在发送请求前添加用户信息的请求头:

public class DefaultFeignConfig {
    @Bean
    public RequestInterceptor userInfoRequestInterceptor(){
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate requestTemplate) {
                Long user = UserContext.getUser();
                if(user != null)
                  requestTemplate.header("user-info", user.toString());
            }
        };
    }
}

 四、nacos配置管理

引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

登录nacos后台添加配置

spring:

datasource:

url: jdbc:mysql://${hm.db.host}:${hm.db.port:3306}/${hm.db.database}}?characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai

driver-class-name: com.mysql.cj.jdbc.Driver

username: root

password: ${hm.db.pw}

mybatis-plus:

configuration:

default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

global-config:

db-config:

update-strategy: not_null

id-type: auto

 编写bootstrap.yml
该文件读取在application.yml之前用于读取nacos中的配置文件

application.yml:

 

启动查看日志:

 成功拉取配置文件 。

配置热部署:

1.@ConfigurationProperties

@Data
@Component
@ConfigurationProperties(prefix = "hm.cart")
public class CartProperties {
    private Integer maxItems;
}

2.@RefreshScope + @Value

@Data
@Component
@RefreshScope
public class CartProperties {
    @Value("${hm.cart.maxItems}")
    private Integer maxItems;
}

nacos配置:

五、服务保护(sentinel) 

下载:Release v1.8.7 · alibaba/Sentinel · GitHub

下载完成后可以直接在本地java -jar 运行。 

官方中文文档:

introduction | Sentinel

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

 访问ip:8088

 账号:sentinel 密码:sentinel

服务yaml配置

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
      eager: true
      #请求方法前缀
      http-method-specify: true
#feign整合sentinel,用于管理服务间请求
feign:
  sentinel:
    enabled: true

启动项目并访问任意一个端口。

 控制接口限流:

 线程隔离:

熔断:

超出限流Fallback处理:

@Slf4j
public class ItemClientFallbackFactory implements FallbackFactory<ItemClient> {
    @Override
    public ItemClient create(Throwable cause) {
        return new ItemClient() {
            @Override
            public List<ItemDTO> queryItemByIds(Collection<Long> ids) {
                log.error("查询异常", cause);
                return Collections.emptyList();
            }

            @Override
            public void deductStock(List<OrderDetailDTO> items) {
                throw new RuntimeException(cause);
            }
        };
    }
}

public class DefaultFeignConfig {
    @Bean
    public ItemClientFallbackFactory itemClientFallbackFactory(){
        return new ItemClientFallbackFactory();
    }
}

设置qps为1,一秒只接收一次请求,方便测试。

进入swagger调试:

一秒内第一次:

一秒内第二次: 

后端:

 sentinel配置持久化 (使用nacos配置)

引入对呀sentinel版本的依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.8.6</version>
</dependency>

nacos创建配置文件sentinel.json配置:

[

 {

  "resource": "GET:/carts",

  "count": 200.0,

  "grade": 0,

  "slowRatioThreshold": 0.5,

  "timeWindow": 10

 }

]

 添加springboot配置sentinel下:

datasource:
  ds2:
    nacos:
      server-addr: xxx.xxx.xxx.xxx:8848
      data-id: sentinel.json
      group-id: DEFAULT_GROUP
      data-type: json
      rule-type: degrade

重启服务 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决Pycharm全局搜索与输入法简繁切换快捷键冲突问题

Pycharm中全局搜索快捷键Ctrl Shift F 如图所示&#xff1a; 微软输入法简繁切换快捷键设置&#xff1a; 解决办法&#xff1a; 关掉输入法的切换功能即可&#xff0c;或者更改简繁切换快捷键&#xff0c;毕竟简繁切换使用频率极低。

特别的时钟:上次那个时钟布局和计算有问题,重新修改一下,用JS创建180多个li标签,自动生成数字

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>特别的时钟</title> </head> <st…

Github Action Bot 开发教程

Github Action Bot 开发教程 在使用 Github 时&#xff0c;你可能在一些著名的开源项目&#xff0c;例如 Kubernetes&#xff0c;Istio 中看到如下的一些评论&#xff1a; /lgtm /retest /area bug /assign xxxx ...等等&#xff0c;诸如此类的一些功能性评论。在这些评论出现…

合泰杯(HT32F52352)RTC的应用(计时)--->掉电不丢失VBAT(代码已经实现附带源码)

摘要 在HT32F52352合泰单片机开发中&#xff0c;rtc在网上还是挺少人应用的&#xff0c;找了很久没什么资料&#xff0c;现在我根据手册和官方的代码进行配置理解。 RTC在嵌入式单片机中是一个很重要的应用资源。 记录事件时间戳&#xff1a;RTC可以记录事件发生的精确时间&…

踏上R语言之旅:解锁数据世界的神秘密码(四)

文章目录 前言一、多元线性回归1.多元线性回归模型的建立2.多元线性回归模型的检验 二、多元线性相关分析1.矩阵相关分析2.复相关分析 三、回归变量的选择方法1.变量选择准则2.变量选择的常用准则3.逐步回归分析 总结 前言 回归分析研究的主要对象是客观事物变量间的统计关系。…

Macs Fan Control Pro for mac激活版:macOS 平台的风扇控制软件

Macs Fan Control Pro是一款用于 macOS 平台的风扇控制软件&#xff0c;它允许用户监控和调整 Mac 电脑的风扇转速。以下是该软件的一些特点和功能&#xff1a; Macs Fan Control Pro for mac激活版下载 风扇监控&#xff1a;Macs Fan Control Pro 提供实时的风扇转速监控&…

vue+elementui(笔记)

vueelementui 表格 <div class"tableStyle"><el-table :data"pointsSettingsTableData" style"width: 70%" :stripe"true" size"mini"header-cell-class-name"headerClassName" :cell-style"{ tex…

Llama3 在线试用与本地部署

美国当地时间4月18日&#xff0c;Meta 开源了 Llama3 大模型&#xff0c;目前开源版本为 8B 和 70B 。Llama 3 模型相比 Llama 2 具有重大飞跃&#xff0c;并在 8B 和 70B 参数尺度上建立了 LLM 模型的新技术。由于预训练和后训练的改进&#xff0c;Llama3 模型是目前在 8B 和 …

应急响应-webserver

一.环境准备 1.镜像文件 2.任务说明 3.用户密码 二.应急响应 环境启动 1.导入镜像文件并修改网络 2.远程连接 ss -ntl #列出系统中运行的所有进程 用远程连接工具连接 任务一 Linux 服务日志默认存储在/var/log目录下 默认网站根目录&#xff1a;/var/www/html/ 1.查看…

【Doris系列】 SQL 多方言兼容

目前 Doris 引擎提供了两种方式实现对 sql 多方言的支持。即&#xff0c;提交指定方言的 sql&#xff0c;Doris 可以成功解析&#xff0c;并返回正确的计算结果。本文就简单来测试验证下这两种方式的效果。 一、Doris Sql Convertor Doris 官方提供了一个 sql convertor 工具…

ES全文检索支持拼音和繁简检索

ES全文检索支持拼音和繁简检索 1. 实现目标2. 引入pinyin插件2.1 编译 elasticsearch-analysis-pinyin 插件2.2 安装拼音插件 3. 引入ik分词器插件3.1 已有作者编译后的包文件3.2 只有源代码的版本3.3 安装ik分词插件 4. 建立es索引5.测试检索6. 繁简转换 1. 实现目标 ES检索时…

力扣33. 搜索旋转排序数组

Problem: 33. 搜索旋转排序数组 文章目录 题目描述思路复杂度Code 题目描述 思路 1.初始化左右指针&#xff1a;首先&#xff0c;定义两个指针left和right&#xff0c;分别指向数组的开始和结束位置。 2.计算中间值&#xff1a;在left和right之间找到中间位置mid。 3.比较中间值…

使用Python爬取淘宝商品并做数据分析

使用Python爬取淘宝商品并做数据分析&#xff0c;可以按照以下步骤进行操作&#xff1a; 确定需求&#xff1a;确定要爬取的淘宝商品的种类、数量、关键词等信息。 编写爬虫程序&#xff1a;使用Python编写爬虫程序&#xff0c;通过模拟浏览器请求&#xff0c;获取淘宝商品的页…

ffmpeg音视频裁剪

音视频裁剪&#xff0c;通常会依据时间轴为基准&#xff0c;从某个起始点到终止点的音视频截取出来&#xff0c;当然音视频文件中存在多路流&#xff0c;所对每一组流进行裁剪 基础概念&#xff1a; 编码帧的分类&#xff1a; I帧(Intra coded frames): 关键帧&#xff0c;…

SpringCloud学习笔记(一)微服务介绍、服务拆分和RestTemplate远程调用、Eureka注册中心

文章目录 1 认识微服务1.1 单体架构1.2 分布式架构1.3 微服务1.4 SpringCloud1.5 总结 2 服务拆分与远程调用2.1 服务拆分原则2.2 服务拆分示例2.2.1 搭建项目2.2.2 创建数据库和表2.2.3 实现远程调用2.2.3.1 需求描述2.2.3.2 注册RestTemplate2.2.3.3 实现远程调用 2.2.4 提供…

【网络】HTTP协议

文章目录 一. 认识 URL1. URL 初识2. URL 的组成① 协议名称② 域名③ 端口号④ 文件路径⑤ 查询参数 3. URL中的字符3.1 合法字符3.2 保留字符3.3 其他字符3.4 URL中的字符总结 二. HTTP 协议1. HTTP 介绍2. 请求报文2.1 请求报文的格式2.2 请求方法介绍2.3 请求报文中常见的 …

【LeetCode:1103. 分糖果 II + 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

CUDA架构介绍与设计模式解析

文章目录 **CUDA**架构介绍与设计模式解析**1** CUDA 介绍CUDA发展历程CUDA主要特性CUDA系统架构CUDA应用场景编程语言支持CUDA计算过程线程层次存储层次 **2** CUDA 系统架构分层架构并行计算模式生产-消费者模式工作池模式异步编程模式 **3** CUDA 中的设计模式工厂模式策略模…

电脑技巧:推荐一款非常好用的媒体播放器PotPlayer

目录 一、 软件简介 二、功能介绍 2.1 格式兼容性强 2.2 高清播放与硬件加速 2.3 自定义皮肤与界面布局 2.4 多音轨切换与音效增强 2.5 字幕支持与编辑 2.6 视频截图与录像 2.7 网络流媒体播放 三、软件特色 四、使用技巧 五、总结 一、 软件简介 PotPlayer播放器 …

【MATLAB源码-第201期】基于matlab的黏菌群优化算法(SMA)无人机三维路径规划,输出做短路径图和适应度曲线

操作环境&#xff1a; MATLAB 2022a 1、算法描述 黏菌优化算法&#xff08;Slime Mould Algorithm, SMA&#xff09;是一种新颖的启发式优化方法&#xff0c;其灵感来源于自然界中的真菌——黏菌。这种算法模拟了黏菌在寻找食物时的行为和网络形成策略。在本文中&#xff0c…