微服务day03

导入黑马商城项目

创建Mysql服务

由于已有相关项目则要关闭DockerComponent中的已开启的项目


[root@server02 ~]# docker compose down
WARN[0000] /root/docker-compose.yml: `version` is obsolete
[+] Running 4/4
 ✔ Container nginx  Removed                                                0.2s
 ✔ Container hmall  Removed                                                0.4s
 ✔ Container mysql  Removed                                                1.5s
 ✔ Network hmall    Removed                                                0.1s
[root@server02 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@server02 ~]#

创建网络用来连接项目容器

[root@server02 ~]# docker network create hm-net
025bba52632ae4d789c1281fb0114fd10f58fe9b0cf7c998a32c660b2eb889e9
[root@server02 ~]#

创建并运行Mysql容器

[root@server02 ~]# docker run -d \
>   --name mysql \
>   -p 3306:3306 \
>   -e TZ=Asia/Shanghai \
>   -e MYSQL_ROOT_PASSWORD=123 \
>   -v /root/mysql/data:/var/lib/mysql \
>   -v /root/mysql/conf:/etc/mysql/conf.d \
>   -v /root/mysql/init:/docker-entrypoint-initdb.d \
>   --network hm-net\
>   mysql
a88243bf07574804e6a580e66dbf5b885c73c4d72e4a33b288c4d1f1f7541bea
[root@server02 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS                                                  NAMES
a88243bf0757   mysql     "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql
[root@server02 ~]#

导入后端代码

打开准备的后端代码

导入前端代码

将提供的hmail-nginx文件迁移到英文目录下,使用命令行启动

start nginx.exe

单体结构

微服务项目

SpringCloud

微服务的技术栈。

微服务拆分

熟悉黑马商城

黑马商城的组成

拆分原则

服务拆分

黑马商城采用Maven聚合来进行微服务。

案例:拆分服务

拆分商品相关微服务:

远程调用

由于启动类也是一个配置类,因此在启动类添加Bean容器

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

修改后的service文件

@Service
@RequiredArgsConstructor
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {

    private final RestTemplate restTemplate;

    @Override
    public void addItem2Cart(CartFormDTO cartFormDTO) {
        // 1.获取登录用户
        Long userId = UserContext.getUser();

        // 2.判断是否已经存在
        if (checkItemExists(cartFormDTO.getItemId(), userId)) {
            // 2.1.存在,则更新数量
            baseMapper.updateNum(cartFormDTO.getItemId(), userId);
            return;
        }
        // 2.2.不存在,判断是否超过购物车数量
        checkCartsFull(userId);

        // 3.新增购物车条目
        // 3.1.转换PO
        Cart cart = BeanUtils.copyBean(cartFormDTO, Cart.class);
        // 3.2.保存当前用户
        cart.setUserId(userId);
        // 3.3.保存到数据库
        save(cart);
    }

    @Override
    public List<CartVO> queryMyCarts() {
        // 1.查询我的购物车列表
        List<Cart> carts = lambdaQuery().eq(Cart::getUserId, 1L /*TODO UserContext.getUser()*/).list();
        if (CollUtils.isEmpty(carts)) {
            return CollUtils.emptyList();
        }
        // 2.转换VO
        List<CartVO> vos = BeanUtils.copyList(carts, CartVO.class);
        // 3.处理VO中的商品信息
        handleCartItems(vos);
        // 4.返回
        return vos;
    }

    private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id TODO 处理商品信息
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        // 2.查询商品
//        List<ItemDTO> items = itemService.queryItemByIds(itemIds);

        //通过restTemplate查询商品信息
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                "http://localhost:8081/items?ids={ids}",
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<ItemDTO>>() {
                },
                CollUtil.join(itemIds, ",")
        );
        List<ItemDTO> items = response.getBody();
        if (CollUtils.isEmpty(items)) {
            throw new BadRequestException("购物车中商品不存在!");
        }
        // 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());
        }
    }

    @Override
    public void removeByItemIds(Collection<Long> itemIds) {
        // 1.构建删除条件,userId和itemId
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<Cart>();
        queryWrapper.lambda()
                .eq(Cart::getUserId, UserContext.getUser())
                .in(Cart::getItemId, itemIds);
        // 2.删除
        remove(queryWrapper);
    }

    private void checkCartsFull(Long userId) {
        int count = Math.toIntExact(lambdaQuery().eq(Cart::getUserId, userId).count());
        if (count >= 10) {
            throw new BizIllegalException(StrUtil.format("用户购物车课程不能超过{}", 10));
        }
    }

    private boolean checkItemExists(Long itemId, Long userId) {
        int count = Math.toIntExact(lambdaQuery()
                .eq(Cart::getUserId, userId)
                .eq(Cart::getItemId, itemId)
                .count());
        return count > 0;
    }
}

注入RestTemplate来进行信息交互。

 private final RestTemplate restTemplate;

由于springboot不推荐@Autoword注入因此使用无参构造进行注入Lombok中的@RequiredArgsConstructor注解可以将类中所有必要的参数加入无参构造(final),以此进行注入

获取商品信息并返回:

 private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id TODO 处理商品信息
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        // 2.查询商品
//        List<ItemDTO> items = itemService.queryItemByIds(itemIds);

        //通过restTemplate查询商品信息
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                "http://localhost:8081/items?ids={ids}",
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<ItemDTO>>() {
                },
                CollUtil.join(itemIds, ",")
        );
        List<ItemDTO> items = response.getBody();
        if (CollUtils.isEmpty(items)) {
            throw new BadRequestException("购物车中商品不存在!");
        }
        // 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());
        }
    }

修改位置:

  // 2.查询商品
//        List<ItemDTO> items = itemService.queryItemByIds(itemIds);

        //通过restTemplate查询商品信息
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                "http://localhost:8081/items?ids={ids}",//要访问的接口位置
                HttpMethod.GET,//访问的类型
                null,//requestEnitiy设置为空
                new ParameterizedTypeReference<List<ItemDTO>>() {
                },//用以将List<ItemDTO>作为泛型传入
                CollUtil.join(itemIds, ",")//要携带的属性
        );
        List<ItemDTO> items = response.getBody();//获取数据

服务治理

注册中心原理

Nacos注册中心

docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim

1、创建nacos:

在数据库中导入nacos的数据库

2、在docker中创建nacos

  1. 将配置文件导入虚拟机
  2. 将nacos的tar包导入虚拟机,nacos.tar
  3. 上传nacos包到本地镜像
docker load -i nacos.tar
  1. 创建nacos容器
docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim
0
[root@server02 ~]# docker load -i nacos.tar


9c1b6dd6c1e6: Loading layer   83.9MB/83.9MB
13a34b6fff78: Loading layer  5.177MB/5.177MB
8373e87e0617: Loading layer  3.584kB/3.584kB
dc68e54a0b44: Loading layer  109.3MB/109.3MB
445489eb2a14: Loading layer  2.048kB/2.048kB
cb4f3f38c79e: Loading layer  127.6MB/127.6MB
91e3449baf4f: Loading layer   7.68kB/7.68kB
a28384a784e0: Loading layer  5.632kB/5.632kB
8fa6b76bdc24: Loading layer  3.072kB/3.072kB
5f70bf18a086: Loading layer  1.024kB/1.024kB
Loaded image: nacos/nacos-server:v2.1.0-slim
[root@server02 ~]#
[root@server02 ~]#
[root@server02 ~]# dis
REPOSITORY           TAG               IMAGE ID       CREATED        SIZE
root-hmall           latest            3e78751a9f66   42 hours ago   370MB
docker-demo          1.0               9e95eddcf939   43 hours ago   319MB
mysql                latest            be960704dfac   2 weeks ago    602MB
nacos/nacos-server   v2.1.0-slim       49addbd025a1   2 years ago    322MB
openjdk              11.0-jre-buster   57925f2e4cff   2 years ago    301MB
nginx                latest            3f8a4339aadd   6 years ago    108MB
[root@server02 ~]# docker run -d \
> --name nacos \
> --env-file ./nacos/custom.env \
> -p 8848:8848 \
> -p 9848:9848 \
> -p 9849:9849 \
> --restart=always \
> docker ps -a^C
[root@server02 ~]#
[root@server02 ~]# docker run -d \
> --name nacos \
> --env-file ./nacos/custom.env \
> -p 8848:8848 \
> -p 9848:9848 \
> -p 9849:9849 \
> --restart=always \
> nacos/nacos-server:v2.1.0-slim
a46373d69c1dcaf7a8183a21b81aeec3c790e3016d25607e90930e94e08119a6
[root@server02 ~]# dps
CONTAINER ID   IMAGE                            PORTS                                                                                                      STATUS          NAMES
a46373d69c1d   nacos/nacos-server:v2.1.0-slim   0.0.0.0:8848->8848/tcp, :::8848->8848/tcp, 0.0.0.0:9848-9849->9848-9849/tcp, :::9848-9849->9848-9849/tcp   Up 21 seconds   nacos
dc43e5e833fe   mysql                            0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                                       Up 13 minutes   mysql
[root@server02 ~]#

服务注册

服务发现

引入依赖:

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

配置RestTemplate类

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

引入nacos的地址:

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

修改代码:

    private final RestTemplate restTemplate;

    //引入 服务发现 客户端,使用该客户端获取对应的服务列表
    private final DiscoveryClient discoveryClient;
    private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id TODO 处理商品信息
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        // 2.查询商品

        //获取服务列表
        List<ServiceInstance> instances = discoveryClient.getInstances("item-service");

        //进行负载均衡(随机负载均衡)
        ServiceInstance serviceInstance = instances.get(RandomUtil.randomInt(instances.size()));
        //获取该服务的URL
        URI uri = serviceInstance.getUri();

        //通过restTemplate查询商品信息
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                uri+"/items?ids={ids}",
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<ItemDTO>>() {
                },
                CollUtil.join(itemIds, ",")
        );
        List<ItemDTO> items = response.getBody();
        if (CollUtils.isEmpty(items)) {
            throw new BadRequestException("购物车中商品不存在!");
        }
        // 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());
        }
    }

OpenFeign

引入依赖:

  <!--openFeign-->
  <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>

在启动项添加注解:

@EnableFeignClients //启用openfeign


@EnableFeignClients //启用openfeign
@MapperScan("com.hmall.cart.mapper")
@SpringBootApplication
public class CartApplication {
    public static void main(String[] args) {
        SpringApplication.run(CartApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

创建接口:

import com.hmall.cart.domain.dto.ItemDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Collection;
import java.util.List;

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

修改代码:

      //注入bean
private final ItemClient itemClient;

//    private final RestTemplate restTemplate;
//
//    //引入 服务发现 客户端,使用该客户端获取对应的服务列表
//    private final DiscoveryClient discoveryClient;






  private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id TODO 处理商品信息
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
//        // 2.查询商品
        List<ItemDTO> items = itemClient.queryItemByIds(itemIds);
//        //获取服务列表
//        List<ServiceInstance> instances = discoveryClient.getInstances("item-service");
//
//        //进行负载均衡(随机负载均衡)
//        ServiceInstance serviceInstance = instances.get(RandomUtil.randomInt(instances.size()));
//        //获取该服务的URL
//        URI uri = serviceInstance.getUri();
//
//        //通过restTemplate查询商品信息
//        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
//                uri+"/items?ids={ids}",
//                HttpMethod.GET,
//                null,
//                new ParameterizedTypeReference<List<ItemDTO>>() {
//                },
//                CollUtil.join(itemIds, ",")
//        );
//        List<ItemDTO> items = response.getBody();
        if (CollUtils.isEmpty(items)) {
            throw new BadRequestException("购物车中商品不存在!");
        }
        // 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());
        }
    }

连接池

引入okhttp的依赖

<!--OK http 的依赖 -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
</dependency>

修改配置文件,开启连接池

feign:
  okhttp:
    enabled: true # 开启OKHttp功能

最佳实践

采用方法二进行改造

  1. 创建 hm-api 模块。
  2. 在该模块下创建 com.hmall.api.client包和com.hmall.api.dto和com.hmall.api.config包
  3. 在cart-servicer启动项 添加扫描包
  4. @EnableFeignClients(basePackages = "com.hmall.api.client")
  5. 引入模块cart-servicer模块中的代码
@FeignClient("item-service")
public interface ItemClient {
    // 获取商品详情
    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}
@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;
}

日志

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

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

相关文章

Mac如何实现最简单的随时监测实时运行状态的方法

Mac book有着不同于Windows的设计逻辑与交互设计&#xff0c;使得Mac book有着非常棒的使用体验&#xff0c;但是在Mac电脑的使用时间过长时&#xff0c;电脑也会出现响应速度变慢或应用程序崩溃的情况&#xff0c;当发生的时候却不知道什么原因导致的&#xff0c;想要查询电脑…

无需云端!国产开源大语言模型llama.cpp本地实战

作者&#xff1a;高瑞冬 注&#xff1a; 文章是2023年底写的。代码和运行方式虽有些旧&#xff0c;但基本原理一样。现在出来ollama&#xff0c;vllm等工具框架用来本地部署大模型&#xff0c;顺便更新一下。 [TOC](最后有彩蛋) 背景 上海人工智能实验室与商汤科技…

初始JavaEE篇 —— 网络编程(2):了解套接字,从0到1实现回显服务器

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 TCP 与 UDP Socket套接字 UDP TCP 网络基础知识 在一篇文章中&#xff0c;我们了解了基础的网络知识&#xff0c;网络的出…

PVE纵览-从零开始:了解Proxmox Virtual Environment

PVE纵览-从零开始&#xff1a;了解Proxmox Virtual Environment 文章目录 PVE纵览-从零开始&#xff1a;了解Proxmox Virtual Environment摘要什么是Proxmox Virtual EnvironmentPVE的核心功能PVE 优势如何开始使用PVEPVE应用案例总结 关键字&#xff1a; PVE、 虚拟机、 Pr…

08 Oracle数据库故障应对与恢复策略:全面掌握RMAN恢复方法

文章目录 Oracle数据库故障应对与恢复策略&#xff1a;全面掌握RMAN恢复方法一、故障场景及恢复策略1.1 实例失败1.2 介质故障1.3 数据丢失 二、RMAN恢复方法详解2.1 全库恢复2.2 增量恢复2.3 时间点恢复 三、实践与总结 Oracle数据库故障应对与恢复策略&#xff1a;全面掌握RM…

MYSQL隔离性原理——MVCC

表的隐藏字段 表的列包含用户自定义的列和由系统自动创建的隐藏字段。我们介绍3个隐藏字段&#xff0c;不理解也没有关系&#xff0c;理解后面的undo log就懂了&#xff1a; DB_TRX_ID &#xff1a;6 byte&#xff0c;最近修改( 修改/插入 )事务ID&#xff0c;记录创建这条记…

Git超详细教程

Git初始 概念 一个免费开源&#xff0c;分布式的代码版本控制系统&#xff0c;帮助开发团队维护代码 作用 记录代码内容&#xff0c;&#xff0c;切换代码版本&#xff0c;多人开发时高效合并代码内容 如何学&#xff1a; 个人本机使用&#xff1a;Git基础命令和概念 多…

BK3432芯片SPI方式烧录固件方法

前言 本文介绍 BK3432 芯片的烧录授权。该芯片支持的固件烧录方式为 SPI 烧录 。 BK3432 的固件主要由三部分组成&#xff1a;boot stack app&#xff0c;其中&#xff1a; bk3432_ble_app.bin&#xff1a;生成的 App 部分的原始 bin 文件bk3432_ble_app_app.bin&#xff1…

网站架构知识之Ansible进阶(day022)

1.handler触发器 应用场景&#xff1a;一般用于分发配置文件时候&#xff0c;如果配置文件有变化&#xff0c;则重启服务&#xff0c;如果没有变化&#xff0c;则不重启服务 案列01&#xff1a;分发nfs配置文件&#xff0c;若文件发生改变则重启服务 2.when判断 用于给ans运…

陪诊问诊APP开发实战:基于互联网医院系统源码的搭建详解

时下&#xff0c;开发一款功能全面、用户体验良好的陪诊问诊APP成为了医疗行业的一大热点。本文将结合互联网医院系统源码&#xff0c;详细解析陪诊问诊APP的开发过程&#xff0c;为开发者提供实用的开发方案与技术指导。 一、陪诊问诊APP的背景与功能需求 陪诊问诊APP核心目…

稳压二极管详解

目录 1. 工作原理 2. 稳压二极管的伏安特性曲线 3. 正向特性&#xff1a; 4. 反向特性 5. 稳定电压&#xff08;Vz&#xff09; 6. 动态电阻&#xff08;rz&#xff09; 7.最大耗散功率&#xff08;PzM&#xff09; 8. 最大稳定工作电流&#xff08;IzMAX&#xff09;和…

python爬虫案例——网页源码被加密,解密方法全过程

文章目录 1、任务目标2、网页分析3、代码编写1、任务目标 目标网站:https://jzsc.mohurd.gov.cn/data/company,该网站的网页源码被加密了,用于本文测验 要求:解密该网站的网页源码,请求网站并返回解密后的明文数据,网页内容如下: 2、网页分析 进入网站,打开开发者模式,…

K8S简单部署,以及UI界面配置

准备两台服务器K8Smaster和K8Sminion 分别在两台服务器上执行以下代码 #添加hosts解析&#xff1b; cat >/etc/hosts<<EOF 127.0.0.1 localhost localhost.localdomain 192.168.45.133 master1 192.168.45.135 node2 EOF #临时关闭selinux和防火墙&#xff1b; sed …

【微信小程序】基本语法

一、导入小程序 选择代码目录 项目配置文件 appid 当前小程序的 AppIDprojectname 当前小程序的项目名称 变更AppID&#xff08;视情况而定&#xff0c;如果没有开发权限时需要变更成个人的 AppID&#xff09; 二、模板语法 在页面中渲染数据时所用到的一系列语法叫做模板…

kafka中节点如何服役和退役

服役新节点 1&#xff09;新节点准备 &#xff08;1&#xff09;关闭 bigdata03&#xff0c;进行一个快照&#xff0c;并右键执行克隆操作。 &#xff08;2&#xff09;开启 bigdata04&#xff0c;并修改 IP 地址。 vi /etc/sysconfig/network-scripts/ifcfg-ens33修改完记…

红黑树及MySQL 基础架构

红黑树简介及左旋、右旋、变色 红黑树(Red Black Tree)是一种自平衡二叉搜索树(二叉查找树)&#xff0c;是一种特殊的二叉搜索树&#xff0c;在进行插入和删除时通过特定操作保持二叉树自身的平衡&#xff0c;从而获得较高的查找性能。 红黑树的平衡操作通过左旋、右旋和变色来…

ElasticSearch向量检索技术方案介绍

1、背景 在人工智能快速发展的今天&#xff0c;推荐技术、以文搜图、以文搜视频、以图搜图等技术已经得到了广泛的应用&#xff0c;在百度、小红书、抖音、快手等app上随便输入一段文本&#xff0c;搜索结果已不像早些年那么单一&#xff1a;只有一些文字信息&#xff0c;现在的…

MySql中索引为什么用B+树,他有什么特点?时间复杂度是多少?能存多少数据?是不是只能三层?他与B-树有什么不同?还有其它的树你是是否知道?

平衡二叉树 平衡二叉树又被称为AVL树平衡二叉树是一颗空树或者它的左右两个子树的高度差的绝对值不超过1&#xff0c;并且左右子树也是平衡树非叶子节点值大于左子节点值而小于右子节点值非叶子节点最多拥有两个子节点 平衡二叉树的不足之处及时间复杂度 如果每次插入的数据都…

3DMAX城镇建筑区块生成插件TownBlocks使用方法详解

3DMAX城镇建筑区块生成插件TownBlocks使用教程 3DMAX城镇建筑区块生成插件TownBlocks&#xff0c;是一款专为城镇建筑区块生成设计的实用工具&#xff0c;它能够实现从2D轮廓到低多边形城镇建筑群的一键批量转换。该插件不仅操作简便&#xff0c;而且提供了丰富的参数设置选项&…

手机内卷下一站,AI Agent

作者 | 辰纹 来源 | 洞见新研社 2024年除夕夜&#xff0c;OPPO在央视春晚即将开始前举办了一场“史上最短发布会”&#xff0c;OPPO首席产品官刘作虎宣布&#xff0c;“OPPO正式进入AI手机时代”。 春节假期刚过&#xff0c;魅族又公开表示&#xff0c;将停止“传统智能手机…