微服务第一轮

课程文档

目录

一、业务流程

1、登录

Controller中的接口: 

 Service中的实现impl:

Service中的实现impl所继承的接口IService(各种方法): 

VO:

 DTO:

2、搜索商品

​Controller中的接口:

3、购物车

​Controller中的接口:

二、拆分商品服务

1. 创建新module - maven模块,并引入依赖

2. 新建包com.hmall.xx(业务名),添加和修改启动类,新建mapper包、domain包 - service包 - controller包

3. 拷贝并修改yaml配置文件到resources中,分别修改 端口号、服务名称、datasource(需创建sql datebase)、swagger接口文档说明与controller扫描包

4.domain,mapper,service,controller包代码 

5. 刷新maven,添加该业务模块启动项到Services中,并把Active profiles 修改为 local

6. 运行,在访问地址后面添加doc.html访问swagger接口文档,进行调试

​三、拆分购物车服务

四、服务调用(RPC)

RestTemplate 

远程直接调用

五、Nacos注册中心

服务注册

 1、添加依赖,配置Nacos

 2、启动服务,访问http://192.168.150.101:8848/nacos/控制台,可以发现服务注册成功:

​服务发现

1、  添加依赖,配置Nacos

 2、根据负载均衡算法发现并调用方法


 

一、业务流程

1、登录

Controller中的接口: 


@Api(tags = "用户相关接口")
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {private final IUserService userService;@ApiOperation("用户登录接口")@PostMapping("login")public UserLoginVO login(@RequestBody @Validated LoginFormDTO loginFormDTO){return userService.login(loginFormDTO);}
}

 Service中的实现impl:

public interface IUserService extends IService<User> {UserLoginVO login(LoginFormDTO loginFormDTO);void deductMoney(String pw, Integer totalFee);
}

Service中的实现impl所继承的接口IService(各种方法): 


public interface IService<T> {int DEFAULT_BATCH_SIZE = 1000;default boolean save(T entity) {return SqlHelper.retBool(this.getBaseMapper().insert(entity));}@Transactional(rollbackFor = {Exception.class})default boolean saveBatch(Collection<T> entityList) {return this.saveBatch(entityList, 1000);}boolean saveBatch(Collection<T> entityList, int batchSize);@Transactional(rollbackFor = {Exception.class})default boolean saveOrUpdateBatch(Collection<T> entityList) {return this.saveOrUpdateBatch(entityList, 1000);}boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
}

VO:

@Data
public class UserLoginVO {private String token;private Long userId;private String username;private Integer balance;
}

 DTO:

@Data
@ApiModel(description = "登录表单实体")
public class LoginFormDTO {@ApiModelProperty(value = "用户名", required = true)@NotNull(message = "用户名不能为空")private String username;@NotNull(message = "密码不能为空")@ApiModelProperty(value = "用户名", required = true)private String password;@ApiModelProperty(value = "是否记住我", required = false)private Boolean rememberMe = false;
}

2、搜索商品

在首页搜索框输入关键字手机,点击搜索即可进入搜索列表页面: 

 Controller中的接口:

@Api(tags = "搜索相关接口")
@RestController
@RequestMapping("/search")
@RequiredArgsConstructor
public class SearchController {private final IItemService itemService;@ApiOperation("搜索商品")@GetMapping("/list")public PageDTO<ItemDTO> search(ItemPageQuery query) {// 分页查询Page<Item> result = itemService.lambdaQuery().like(StrUtil.isNotBlank(query.getKey()), Item::getName, query.getKey()).eq(StrUtil.isNotBlank(query.getBrand()), Item::getBrand, query.getBrand()).eq(StrUtil.isNotBlank(query.getCategory()), Item::getCategory, query.getCategory()).eq(Item::getStatus, 1).between(query.getMaxPrice() != null, Item::getPrice, query.getMinPrice(), query.getMaxPrice()).page(query.toMpPage("update_time", false));// 封装并返回return PageDTO.of(result, ItemDTO.class);}
}

3、购物车

在搜索到的商品列表中,点击按钮加入购物车,即可将商品加入购物车:

 加入成功后即可进入购物车列表页,查看自己购物车商品列表:

 Controller中的接口:

@Api(tags = "购物车相关接口")
@RestController
@RequestMapping("/carts")
@RequiredArgsConstructor
public class CartController {private final ICartService cartService;@ApiOperation("添加商品到购物车")@PostMappingpublic void addItem2Cart(@Valid @RequestBody CartFormDTO cartFormDTO){cartService.addItem2Cart(cartFormDTO);}@ApiOperation("更新购物车数据")@PutMappingpublic void updateCart(@RequestBody Cart cart){cartService.updateById(cart);}@ApiOperation("删除购物车中商品")@DeleteMapping("{id}")public void deleteCartItem(@Param ("购物车条目id")@PathVariable("id") Long id){cartService.removeById(id);}@ApiOperation("查询购物车列表")@GetMappingpublic List<CartVO> queryMyCarts(){return cartService.queryMyCarts();}@ApiOperation("批量删除购物车中商品")@ApiImplicitParam(name = "ids", value = "购物车条目id集合")@DeleteMappingpublic void deleteCartItemByIds(@RequestParam("ids") List<Long> ids){cartService.removeByItemIds(ids);}
}

其中,查询购物车列表时,由于要判断商品最新的价格和状态,所以还需要查询商品信息,业务流程如下:

二、拆分商品服务

1. 创建新module - maven模块,并引入依赖

创建新模块 

选择maven模块,并设定JDK版本为11: 

 添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.heima</groupId><artifactId>hmall</artifactId><version>1.0.0</version></parent><groupId>org.qingshui</groupId><artifactId>item-service</artifactId><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--common--><dependency><groupId>com.heima</groupId><artifactId>hm-common</artifactId><version>1.0.0</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--数据库--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-test</artifactId><version>3.3.0</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><scope>test</scope></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

2. 新建包com.hmall.xx(业务名),添加和修改启动类,新建mapper包、domain包 - service包 - controller包

 新建包com.hmall.item: 

 编写启动类ItemApplication:

@MapperScan("com.hmall.item.mapper")
@SpringBootApplication
public class ItemApplication {public static void main(String[] args) {SpringApplication.run(ItemApplication.class, args);}
}

 新建mapper包、domain包 - service包 - controller包:

3. 拷贝并修改yaml配置文件到resources中,分别修改 端口号、服务名称、datasource(需创建sql datebase)、swagger接口文档说明与controller扫描包

从hm-service中拷贝:

修改application.yaml为:

server:port: 8081
spring:application:name: item-serviceprofiles:active: devdatasource:url: jdbc:mysql://${hm.db.host}:3306/hm-item?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: ${hm.db.pw}
mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandlerglobal-config:db-config:update-strategy: not_nullid-type: auto
logging:level:com.hmall: debugpattern:dateformat: HH:mm:ss:SSSfile:path: "logs/${spring.application.name}"
knife4j:enable: trueopenapi:title: 商品服务接口文档description: "信息"email: zhanghuyi@itcast.cnconcat: 虎哥url: https://www.itcast.cnversion: v1.0.0group:default:group-name: defaultapi-rule: packageapi-rule-resources:- com.hmall.item.controller

创建该模块的数据库: 

4.domain,mapper,service,controller包代码 

【1】domain包代码:dto、po、vo、(query)

dto:数据传输对象 

OrderDetailDTO: 

@ApiModel(description = "订单明细条目")
@Data
@Accessors(chain = true)
public class OrderDetailDTO {@ApiModelProperty("商品id")private Long itemId;@ApiModelProperty("商品购买数量")private Integer num;
}

 ItemDTO:


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

 po:实体


@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("item")
public class Item implements Serializable {private static final long serialVersionUID = 1L;/*** 商品id*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** SKU名称*/private String name;/*** 价格(分)*/private Integer price;/*** 库存数量*/private Integer stock;/*** 商品图片*/private String image;/*** 类目名称*/private String category;/*** 品牌名称*/private String brand;/*** 规格*/private String spec;/*** 销量*/private Integer sold;/*** 评论数*/private Integer commentCount;/*** 是否是推广广告,true/false*/@TableField("isAD")private Boolean isAD;/*** 商品状态 1-正常,2-下架,3-删除*/private Integer status;/*** 创建时间*/private LocalDateTime createTime;/*** 更新时间*/private LocalDateTime updateTime;/*** 创建人*/private Long creater;/*** 修改人*/private Long updater;}

vo:视图对象 

在hm-service模块中没有与商品有关的代码。

query:分页查询 

@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description = "商品分页查询条件")
public class ItemPageQuery extends PageQuery {@ApiModelProperty("搜索关键字")private String key;@ApiModelProperty("商品分类")private String category;@ApiModelProperty("商品品牌")private String brand;@ApiModelProperty("价格最小值")private Integer minPrice;@ApiModelProperty("价格最大值")private Integer maxPrice;
}

【2】mapper包代码 :mapper接口 及mapper.xml文件

public interface ItemMapper extends BaseMapper<Item> {@Update("UPDATE item SET stock = stock - #{num} WHERE id = #{itemId}")void updateStock(OrderDetailDTO orderDetail);
}

【3】 service包:service接口及实现类

service接口: 

public interface IItemService extends IService<Item> {void deductStock(List<OrderDetailDTO> items);List<ItemDTO> queryItemByIds(Collection<Long> ids);
}

 修改sqlStatement后的实现类:

@Service
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements IItemService {@Overridepublic void deductStock(List<OrderDetailDTO> items) {String sqlStatement = "com.hmall.mapper.item.ItemMapper.updateStock";boolean r = false;try {r = executeBatch(items, (sqlSession, entity) -> sqlSession.update(sqlStatement, entity));} catch (Exception e) {throw new BizIllegalException("更新库存异常,可能是库存不足!", e);}if (!r) {throw new BizIllegalException("库存不足!");}}@Overridepublic List<ItemDTO> queryItemByIds(Collection<Long> ids) {return BeanUtils.copyList(listByIds(ids), ItemDTO.class);}
}

【4】controller包

@Api(tags = "商品管理相关接口")
@RestController
@RequestMapping("/items")
@RequiredArgsConstructor
public class ItemController {private final IItemService itemService;@ApiOperation("分页查询商品")@GetMapping("/page")public PageDTO<ItemDTO> queryItemByPage(PageQuery query) {// 1.分页查询Page<Item> result = itemService.page(query.toMpPage("update_time", false));// 2.封装并返回return PageDTO.of(result, ItemDTO.class);}@ApiOperation("根据id批量查询商品")@GetMappingpublic List<ItemDTO> queryItemByIds(@RequestParam("ids") List<Long> ids){return itemService.queryItemByIds(ids);}@ApiOperation("根据id查询商品")@GetMapping("{id}")public ItemDTO queryItemById(@PathVariable("id") Long id) {return BeanUtils.copyBean(itemService.getById(id), ItemDTO.class);}@ApiOperation("新增商品")@PostMappingpublic void saveItem(@RequestBody ItemDTO item) {// 新增itemService.save(BeanUtils.copyBean(item, Item.class));}@ApiOperation("更新商品状态")@PutMapping("/status/{id}/{status}")public void updateItemStatus(@PathVariable("id") Long id, @PathVariable("status") Integer status){Item item = new Item();item.setId(id);item.setStatus(status);itemService.updateById(item);}@ApiOperation("更新商品")@PutMappingpublic void updateItem(@RequestBody ItemDTO item) {// 不允许修改商品状态,所以强制设置为null,更新时,就会忽略该字段item.setStatus(null);// 更新itemService.updateById(BeanUtils.copyBean(item, Item.class));}@ApiOperation("根据id删除商品")@DeleteMapping("{id}")public void deleteItemById(@PathVariable("id") Long id) {itemService.removeById(id);}@ApiOperation("批量扣减库存")@PutMapping("/stock/deduct")public void deductStock(@RequestBody List<OrderDetailDTO> items){itemService.deductStock(items);}
}

5. 刷新maven,添加该业务模块启动项到Services中,并把Active profiles 修改为 local

6. 运行,在访问地址后面添加doc.html访问swagger接口文档,进行调试

 三、拆分购物车服务

同上 

四、服务调用(RPC)

背景: 

在拆分的时候,我们发现一个问题:就是购物车业务中需要查询商品信息,但商品信息查询的逻辑全部迁移到了item-service服务,导致我们无法查询。(也就是一个模块要进行查询但是查询代码都在另外一个模块) 

那么问题来了:我们该如何跨服务调用,准确的说,如何在cart-service中获取item-service服务中的提供的商品数据呢? 

 因此,现在查询购物车列表的流程变成了这样:

 假如我们在cart-service中能模拟浏览器,发送http请求到item-service,是不是就实现了跨微服务的远程调用了呢(也就是用Java代码发送Http请求)

RestTemplate 

Spring给我们提供了一个RestTemplate的API,可以方便的实现Http请求的发送。 

其中提供了大量的方法,方便我们发送Http请求,例如: 

我们在cart-service服务中定义一个配置类 

 先将RestTemplate注册为一个Bean:

package com.hmall.cart.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RemoteCallConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

远程直接调用

 在这个过程中,item-service提供了查询接口,cart-service利用Http请求调用该接口。因此item-service可以称为服务的提供者,而cart-service则称为服务的消费者或服务调用者。

五、Nacos注册中心

背景: 

RPC通过Http请求实现了跨微服务的远程调用,这种手动发送Http请求的方式存在一些问题。 

试想一下,假如商品微服务被调用较多,为了应对更高的并发,我们进行了多实例部署,如图: 

此时,每个item-service的实例其IP或端口不同,问题来了:

  • item-service这么多实例,cart-service如何知道每一个实例的地址?

  • http请求要写url地址,cart-service服务到底该调用哪个实例呢?

  • 如果在运行过程中,某一个item-service实例宕机,cart-service依然在调用该怎么办?

  • 如果并发太高,item-service临时多部署了N台实例,cart-service如何知道新实例的地址?

这时我们需要注册中心 (其实也是建立一个连接池)

流程如下:

  • 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心

  • 调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可能多实例部署)

  • 调用者自己对实例列表负载均衡,挑选一个实例

  • 调用者向该实例发起远程调用

当服务提供者的实例宕机或者启动新实例时,调用者如何得知呢?

  • 服务提供者会定期向注册中心发送请求,报告自己的健康状态(心跳请求)

  • 当注册中心长时间收不到提供者的心跳时,会认为该实例宕机,将其从服务的实例列表中剔除

  • 当服务有新实例启动时,会发送注册服务请求,其信息会被记录在注册中心的服务实例列表

  • 当注册中心服务列表变更时,会主动通知微服务,更新本地服务列表

服务注册

将模块(微服务)注册到Nacos 

 1、添加依赖,配置Nacos

item-servicepom.xml中添加依赖:

<!--nacos 服务注册发现-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

 在item-serviceapplication.yml中添加nacos地址配置:

将nacos地址修改为自己的虚拟机地址 

spring:application:name: item-service # 服务名称cloud:nacos:server-addr: 192.168.150.101:8848 # nacos地址

 2、启动服务,访问http://192.168.150.101:8848/nacos/控制台,可以发现服务注册成功:

 服务发现

服务的消费者要去nacos订阅服务,这个过程就是服务发现 。

1、  添加依赖,配置Nacos

服务发现除了要引入nacos依赖以外,由于还需要负载均衡,因此要引入SpringCloud提供的LoadBalancer依赖。

我们在cart-service中的pom.xml中添加下面的依赖:

<!--nacos 服务注册发现-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

 cart-serviceapplication.yml中添加nacos地址配置:

spring:cloud:nacos:server-addr: 192.168.150.101:8848

 2、根据负载均衡算法发现并调用方法

接下来,服务调用者cart-service就可以去订阅item-service服务了。不过item-service有多个实例,而真正发起调用时只需要知道一个实例的地址。

因此,服务调用者必须利用负载均衡的算法,从多个实例中挑选一个去访问。常见的负载均衡算法有:

  • 随机

  • 轮询

  • IP的hash

  • 最近最少访问

  • ...

这里我们可以选择最简单的随机负载均衡。

另外,服务发现需要用到一个工具,DiscoveryClient,SpringCloud已经帮我们自动装配,我们可以直接注入使用:

 

 接下来,我们就可以对原来的远程调用做修改了,之前调用时我们需要写死服务提供者的IP和端口:

 但现在不需要了,我们通过DiscoveryClient发现服务实例列表,然后通过负载均衡算法,选择一个实例去调用:

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

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

相关文章

【亚马逊云科技 CSDN 联合巨献】 「对话AI 构建者:从基础到应用的 LLM 全景培训」 限时免费!

&#x1f680;&#x1f31f;【亚马逊云科技 & CSDN 联合巨献】 &#x1f4da;「对话AI 构建者&#xff1a;从基础到应用的 LLM 全景培训」&#x1f525; 限时免费&#xff01; &#x1f4c6; 抓紧时间&#xff01;6月7日前注册&#xff0c;原价 399&#xff0c;现在仅需 0…

C基础与SDK调试方法

REVIEW 上次学习了一下软件使用流程zynq PS点灯-CSDN博客 本次学习一下C编程基础与调试方法 1. 硬件编程原理 小梅哥视频链接&#xff1a; 07_Xilinx嵌入式裸机硬件编程原理_哔哩哔哩_bilibili 对应的课程笔记&#xff1a;【zynq课程笔记】【裸机】【第7课 】【硬件编程原理…

C++ STL - 容器

C STL&#xff08;标准模板库&#xff09;中的容器是一组通用的、可复用的数据结构&#xff0c;用于存储和管理不同类型的数据。 目录 零. 简介&#xff1a; 一 . vector&#xff08;动态数组&#xff09; 二. list&#xff08;双向链表&#xff09; 三. deque&#xff08…

yolov8摔倒检测(包含数据集+训练好的模型)

基于先进的YOLOv8模型&#xff0c;实现了一套高效可靠的人体摔倒检测系统。YOLOv8作为YOLO系列的最新成员&#xff0c;以其卓越的检测速度和准确性&#xff0c;在计算机视觉领域尤其是目标检测任务中表现出色。本系统不仅能够实时处理视频流或监控画面&#xff0c;还能对静态图…

SwiftUI中Menu和ControlGroup的使用

本篇文章主要介绍一下Menu组件和ControlGroup组件的使用。Menu组件是在iOS 14&#xff08;tvOS 17&#xff09;推出的一个组件&#xff0c;点击后提供一个可选择的操作列表。ControlGroup组件是一个容器视图&#xff0c;以视觉上适当的方式为给定的上下文显示语义相关的控件&am…

【面试干货】SQL语言分类

【面试干货】SQL语言分类 1、数据查询语言&#xff08;DQL&#xff09;2、数据操纵语言&#xff08;DML&#xff09;3、数据定义语言&#xff08;DDL&#xff09;4、数据控制语言&#xff08;DCL&#xff09;5、结语 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收…

使用gradio库实现Web应用,允许用户上传图像,并使用YOLOv8模型对图像进行目标检测。

一、Gradio Gradio 详细介绍 Gradio 是一个用于构建和分享机器学习模型和数据科学应用的开源Python库。它简化了创建交互式Web界面的过程&#xff0c;让开发者可以快速搭建原型并与他人分享。 主要特性 易用性&#xff1a; 无需前端开发经验&#xff1a;只需几行Python代码就…

论工业交换机的工业级芯片的重要性

工业交换机作为工业网络中的重要设备&#xff0c;其性能和稳定性对整个工业生产过程至关重要。而工业级芯片作为工业交换机的核心组成部分&#xff0c;更是承载着重要的功能和责任。工业级芯片具有承受恶劣环境的能力&#xff0c;能够在高温、高压、强电磁干扰等恶劣条件下稳定…

html+CSS+js部分基础运用15

1、完成输入框内容的实时反向输出。 2、银行账户余额变动自动通知项目。 设计要求&#xff1a;单击按钮后&#xff0c;余额按照输入框的数额减少&#xff0c;同时将按钮式的提示信息&#xff08;金额&#xff09;同步改变。利用侦听属性实现余额发生变化时发出提示信息&#x…

Django render()函数页面渲染

1&#xff0c; render() 函数 在Django框架中&#xff0c;render() 函数是一个非常有用的快捷方式&#xff0c;用于从视图函数返回一个完整的HTTP响应。它负责将给定的模板与上下文数据结合&#xff0c;渲染出最终的HTML页面&#xff0c;并返回一个HttpResponse对象。 from d…

全能大模型AIGC产品的使用体验、选择倾向与未来展望

随着人工智能技术的迅猛发展&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;领域正迎来前所未有的繁荣。其中&#xff0c;全能大模型产品以其强大的生成能力和广泛的应用场景&#xff0c;吸引了众多用户的关注。腾讯元宝APP的上线更是为这一领域注入了新的活力。本文…

第10周 企业认证、分布式事务,分布式锁方案落地

第10周 企业认证、分布式事务,分布式锁方案落地 1. 基于Redis提高请求响应**********************************************************************************************本周我们将对企业入驻认证的流程进行落地,并且结合分布式缓存中间件Redis与Redisson进行相关的技术…

企业(园区)智慧能源双碳平台解决方案

园区作为工业企业集聚区&#xff0c;在提供了大量基础设施和公共服务的同时也成为了碳排放的主要源头。工业园区的耗能约占全社会总耗能的69%&#xff0c;碳排放占全国总排放约31%。工业园区节能、减耗、提质、减碳工作的落实&#xff0c;是我国实现碳达峰碳中和目标的必然要求…

【python】ModuleNotFoundError: No module named ‘timm’

成功解决“ModuleNotFoundError: No module named ‘timm’”错误的全面指南 一、引言 在Python编程中&#xff0c;经常会遇到各种导入模块的错误&#xff0c;其中“ModuleNotFoundError: No module named ‘timm’”就是一个典型的例子。这个错误意味着你的Python环境中没有安…

Web安全:Web体系架构存在的安全问题和解决方案

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…

【毕业设计之微信小程序系列】基于微信小程序的餐厅点餐小程序的设计与实现

《基于微信小程序的餐厅点餐小程序的设计与实现》 项目效果图 目录大纲 摘要 1、选题及其意义 1.1、设计项目的名称 1.2、研究意义 2、需求分析 2.1、用户需求分析 2.2、功能需求分析 2.3、非功能需求分析 3、系统相关技术概述 3.1、餐饮平台开发相关技术 3.1.1、微信小程序 …

读AI未来进行式笔记04数字医疗与机器人

1. 数字医疗 1.1. 20世纪的“现代医学”得益于史无前例的科学突破&#xff0c;使得医疗的方方面面都得到改善&#xff0c;让人类预期寿命从1900年的31岁提高到2017年的72岁 1.2. 现有的医疗数据库和流程将实现数字化 1.2.1. 患者记录 1.2.…

实时语音交互数字人解决方案,满足不同场景需求

北京美摄网络科技有限公司凭借其领先的实时语音交互数字人解决方案&#xff0c;为企业带来了全新的沟通体验与商业机遇。 一、技术革新&#xff0c;开启交互新篇章 美摄科技实时语音交互数字人解决方案&#xff0c;以先进的人工智能和机器学习技术为基础&#xff0c;实现了文…

批量提取 Word 文档中的全部图片

步骤 1、打开 WinRAR 任选一个现成的压缩包双击打开 WinRAR &#xff0c;或从开始菜单打开 WinRAR 2、直接把要提取图片的 Word 文档拖入 WinRAR 菜单区域 1 → 2 → 3&#xff0c;WinRAR 资源管理目录中的 media 就是该 Word 文档所要提取的全部图片所在文件夹 按住&#x…

人工智能任务5-高级算法工程师需要学习哪些课程与掌握哪些能力

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能的任务5-高级算法工程师需要学习哪些课程&#xff0c;需要掌握哪些能力。高级算法工程师需要掌握的算法模型有&#xff1a;人脸检测模型MTCNN&#xff0c;人脸识别方法Siamese network、center loss、softm…