微服务架构中的精妙设计:环境和工程搭建

news2025/4/2 6:13:52

 一.前期准备

1.1开发环境安装

Oracle从JDK9开始每半年发布⼀个新版本, 新版本发布后, ⽼版本就不再进⾏维护. 但是会有⼏个⻓期维护的版本.
⽬前⻓期维护的版本有: JDK8, JDK11, JDK17, JDK21
在 JDK版本的选择上,尽量选择⻓期维护的版本.
为什么选择JDK17?
Spring Cloud 是基于 SpringBoot 进⾏开发的, SpringBoot 3.X以下的版本, Spring官⽅已不再进⾏维护(还可以继续使⽤), SpringBoot 3.X的版本, 使⽤的JDK版本基线为JDK17. 鉴于JDK21 是2023.09⽉发布的, 很多功能还没有在⽣产环境验证, 所以选择使⽤JDK17来搭建

 Mysql安装版本8.0即可

1.2分析需求

⼀个电商平台包含的内容⾮常多, 以京东为例, 仅从首页上就可以看到巨多的功能

我们该如何实现呢? 如果把这些功能全部写在⼀个服务里, 这个服务将是巨⼤的.
巨多的会员, 巨⼤的流量, 微服务架构是最好的选择.
微服务应用开发的第⼀步, 就是服务拆分. 拆分后才能进⾏"各自开发

1.3服务拆分原则

微服务到底多⼩才算"微", 这个在业界并没有明确的标准. 微服务并不是越⼩越好, 服务越⼩, 微服务架构的优点和缺点都会越来越明显.
服务越⼩, 微服务的独⽴性就会越来越⾼, 但同时, 微服务的数量也会越多, 管理这些微服务的难度也会提⾼. 所以服务拆分也要考虑场景

1.3.1单⼀职责原则

单⼀职责原则原本是⾯向对象设计中的⼀个基本原则, 它指的是⼀个类应该专注于单⼀功能. 不要存在多于⼀个导致类变更的原因
在微服务架构中, ⼀个微服务也应该只负责⼀个功能或业务领域, 每个服务应该有清晰的定义和边界, 只关注⾃⼰的特定业务领域
组织团队也是, ⼀个⼈专注做⼀件事情的效率远高于同时关注多件事情

 比如电商系统:

1.3.2服务自治

服务⾃治是指每个微服务都应该具备⾼度⾃治的能⼒, 即每个服务要能做到独⽴开发, 独⽴测试, 独⽴构建, 独⽴部署, 独⽴运⾏.(麻雀虽小,五脏俱全)
以上⾯的电商系统为例,每⼀个微服务应该有⾃⼰的存储, 配置,在进⾏开发, 构建, 部署, 运⾏和测试时,并不需要过多关注其他微服务的状态和数据

1.3.3单向依赖

微服务之间需要做到单向依赖, 严禁循环依赖, 双向依赖
  • 循环依赖: A -> B -> C ->A
  • 双向依赖: A -> B, B -> A

如果⼀些场景确实无法避免循环依赖或者双向依赖, 可以考虑使用消息队列等其他方式来实现

补充:

微服务架构并⽆标准架构, 合适的就是最好的
在架构设计的过程中, 坚持 "合适优于业界领先", 避免"过度设计"(为了设计⽽设计).

1.4设置需求

⼀个完整的电商系统是庞⼤的, 重点关注如何使⽤Spring Cloud解决微服务架构中遇到的问题
以订单列表为例:
我们简单来考虑, 这个列表提供了以下信息:
  • 订单列表
  • 商品信息
根据服务的单⼀职责原则, 我们把服务进⾏拆分为: 订单服务, 商品服务
订单服务: 提供订单ID, 获取订单详细信息
商品服务: 根据商品ID, 返回商品详细信息.

二.项目搭建

Spring Cloud 是基于SpringBoot搭建的, 所以Spring Cloud 版本与SpringBoot版本有关 

 该项⽬中使⽤的SpringBoot 版本为 3.1.6, 对应的Spring Cloud版本应该为2022.0.x, 选择任⼀就可以

2.1数据准备

 根据服务自治原则, 每个服务都应有自己独立的数据库

订单服务数据库信息:
-- 订单服务

-- 建库
create database if not exists cloud_order charset utf8mb4;

use cloud_order;
-- 订单表
DROP TABLE IF EXISTS order_detail;
CREATE TABLE order_detail (
        `id` INT NOT NULL AUTO_INCREMENT COMMENT '订单id',
        `user_id` BIGINT ( 20 ) NOT NULL COMMENT '用户ID',
        `product_id` BIGINT ( 20 ) NULL COMMENT '产品id',
        `num` INT ( 10 ) NULL DEFAULT 0 COMMENT '下单数量',
        `price` BIGINT ( 20 ) NOT NULL COMMENT '实付款',
        `delete_flag` TINYINT ( 4 ) NULL DEFAULT 0,
        `create_time` DATETIME DEFAULT now(),
        `update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( id )) ENGINE = INNODB DEFAULT CHARACTER 
SET = utf8mb4 COMMENT = '订单表';

-- 数据初始化
insert into order_detail (user_id,product_id,num,price)
values
(2001, 1001,1,99), (2002, 1002,1,30), (2001, 1003,1,40),
(2003, 1004,3,58), (2004, 1005,7,85), (2005, 1006,7,94);

产品服务数据库信息 

-- 产品服务
create database if not exists cloud_product charset utf8mb4;

-- 产品表
use cloud_product;
DROP TABLE IF EXISTS product_detail;
CREATE TABLE product_detail (
        `id` INT NOT NULL AUTO_INCREMENT COMMENT '产品id',
        `product_name` varchar ( 128 ) NULL COMMENT '产品名称',
        `product_price` BIGINT ( 20 ) NOT NULL COMMENT '产品价格',
        `state` TINYINT ( 4 ) NULL DEFAULT 0 COMMENT '产品状态 0-有效 1-下架',
        `create_time` DATETIME DEFAULT now(),
        `update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( id )) ENGINE = INNODB DEFAULT CHARACTER 
SET = utf8mb4 COMMENT = '产品表';

-- 数据初始化
insert into product_detail (id, product_name,product_price,state)
values
(1001,"T恤", 101, 0), (1002, "短袖",30, 0), (1003, "短裤",44, 0), 
(1004, "卫衣",58, 0), (1005, "马甲",98, 0),(1006,"羽绒服", 101, 0), 
(1007, "冲锋衣",30, 0), (1008, "袜子",44, 0), (1009, "鞋子",58, 0),
(10010, "毛衣",98, 0);

2.2程搭建

 项目创建目前有两种:

  • 使用JavaEE的方式,使用IDEA分别创建两个项目,一个项目一个窗口(麻烦)
  • 采用父子工程的方式搭建(推荐)

1.创建父工程 

2.删除src文件(因为不需要编写代码)

3.完善pom.xml文件信息

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <java.version>17</java.version>
        <mybatis.version>3.0.3</mybatis.version>
        <mysql.version>8.0.33</mysql.version>
        <spring-cloud.version>2022.0.3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <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>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <dependency>
                <groupId>com.mysql</groupId>
                <artifactId>mysql-connector-j</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter-test</artifactId>
                <version>${mybatis.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

补充: 

pom文件DependencyManagement Dependencies区别: 

dependencies :将所依赖的jar直接加到项⽬中. ⼦项⽬也会继承该依赖 

dependencyManagement :dependencyManagement :只是声明依赖, 并不实现Jar包引⼊. 如果⼦项⽬需要⽤到相关依赖,需要显式声明. 如果⼦项⽬没有指定具体版本, 会从父项目中读取version. 如果⼦项⽬中指定了版本号,就会使⽤⼦项⽬中指定的jar版本. 此外父⼯程的打包⽅式应该是pom,不是jar, 这⾥需要⼿动使⽤ packaging 来声明.

4.创建两个子项目(order-service , product-service)

  

 

 此时父项目的pom文件就会多出modul

5.给order.pom文件和 product.pom文件添加必要的依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
    </dependency>
    <!--mybatis-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
     <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/**</include>
                </includes>
            </resource>
    </resources>
</build>


 2.3编写order服务

 1.给order子项目创建order包 - 编写启动类

package Order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}

2.编写application.yml配置文件

开始编写业务代码

订单服务:

  • 根据订单ID,返回订单详情

3.先写实体类

package order.model;

import lombok.Data;

import java.util.Date;

@Data
public class OrderInfo {
    private Integer id;
    private Integer userId;
    private Integer productId;
    private Integer num;
    private Integer price;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

4.编写mapper接口 

package order.mapper;

import order.model.OrderInfo;
import org.apache.ibatis.annotations.Select;

public interface OrderMapper {
    @Select("select * from order_detail where id = #{orderId}")
    OrderInfo selectOrderById(Integer orderId);//先声明方法
}

5,编写service Service主要也是从mapper接口调用订单的信息

package order.service;

import order.mapper.OrderMapper;
import order.model.OrderInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;//注入这个接口

    public OrderInfo selectOrderById(Integer orderId){
        return orderMapper.selectOrderById(orderId);
    }
}

6.编写controller 接口

package order.controller;

import order.model.OrderInfo;
import order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("order")
@RestController
public class OrderController {
    @Autowired
    private OrderService orderService;

    @RequestMapping("/{orderId}")
    public OrderInfo getOrderById(@PathVariable("orderId") Integer orderId){
        return orderService.selectOrderById(orderId);
    }
}

启动项目失败,

原因:忘记在mapper接口添加@Mapper注解

 7.项目启动成功耶耶

2.4编写product服务

给product子项目也跟上述操作类似(代码就不粘贴了)

1.编写启动类

 2.配置yml文件(注意修改端口号成9090,数据库名也要修改)

开始编写业务代码:

  • 根据商品ID,返回商品信息

 1.编写实体类信息

2.编写返回商品信息接口

 

3.编写service层

4.编写controller控制层

 5.启动项目成功


 2.5远程调用

实现两个子项目进行交互,因为订单信息里面肯定需要商品信息嘛

根据订单查询订单信息时,根据订单里产品ID,获取产品的详细信息

实现思路: order-service服务向product-service服务发送⼀个http请求, 把得到的返回结果, 和订单结果融合在⼀起, 返回给调用方.


实现方式: 采用Spring 提供的RestTemplate 

1.在将product的实体类复制到order的实体类,并在order实体类添加product类信息

2.创建config包 -  创建HTTP对象 - 定义RestTemplate

3.在servicec层使用http对象调用  

package order.service;

import order.mapper.OrderMapper;
import order.model.OrderInfo;
import order.model.ProductInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;//注入这个接口

    @Autowired
    private RestTemplate restTemplate;
    public OrderInfo selectOrderById(Integer orderId){
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
        String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();
        ProductInfo productInfo = restTemplate.getForObject(url,ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}

4.两个项目都要启动,然后调用order路径就可以返回product的信息了

三.RestTemplate介绍

RestTemplate 是从 Spring3.0 开始⽀持的⼀个 HTTP 请求⼯具, 它是⼀个同步的 REST API 客⼾端, 提供了常见的REST请求方案的模版

 3.1什么是REST?

 REST(Representational State Transfer), 表现层资源状态转移.

可以把 REST 想象成一个大家都遵循的规则手册,让不同的软件、系统之间能够顺畅地 “交流” 和 “合作”,就像人们说同一种语言能更好地沟通一样。

这里面主要有三个概念:

  1. 资源: ⽹络上的所有事物(文字,图片,视频等等)都可以抽象为资源, 每个资源都有⼀个唯⼀的资源标识符(URI)
  2. 表现层: 资源的表现形式, ⽐如⽂本作为资源, 可以⽤txt格式表现, 也可以通过HTML, XML, JSON等格式来表现, 甚⾄以⼆进制的格式表现.
  3. 状态转移: 访问URI, 也就是客⼾端和服务器的交互过程. 客⼾端⽤到的⼿段,只能是HTTP协议. 这个过程中, 可能会涉及到数据状态的变化. ⽐如对数据的增删改查, 都是状态的转移

 REST 是⼀种设计⻛格, 指资源在⽹络中以某种表现形式进⾏状态转移

简单来说: REST描述的是在网络中Client和Server的⼀种交互形式, REST本⾝不实⽤,实⽤的是如何设计 RESTful API(REST风格的⽹络接⼝)

3.2什么是RESTful? 

REST 是⼀种设计风格, 并没有⼀个明确的标准. 满足这种设计风格的程序或接⼝我们称之为RESTful(从单词字⾯来看就是⼀个形容词). 所以RESTful API 就是满⾜REST架构风格的接⼝.

 RESTful 风格大致有以下⼏个主要特征:

  • 资源: 资源可以是⼀个图⽚, ⾳频, 视频或者JSON格式等⽹络上的⼀个实体, 除了⼀些⼆进制的资源外普通的⽂本资源更多以JSON为载体、⾯向⽤⼾的⼀组数据(通常从数据库中查询⽽得到)
  • 统⼀接⼝: 对资源的操作. ⽐如获取, 创建, 修改和删除. 这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE⽅法. 换⾔⽽知,如果使⽤RESTful⻛格的接⼝, 从接⼝上你可能只能定位其资源,但是⽆法知晓它具体进⾏了什么操作,需要具体了解其发⽣了什么操作动作要从其HTTP请求⽅法类型上进⾏判断

这些内容都是通过HTTP协议来呈现的. 所以RESTful是基于HTTP协议的,RestTemplate 是Spring提供, 封装HTTP调用, 并强制使用RESTful风格. 它会处理HTTP连接和关闭,只需要使用者提供资源的地址和参数即可。

3.3RESTful实践

RESTful⻛格的API 固然很好很规范, 但⼤多数互联⽹公司并没有按照其规则来设计, 因为REST是⼀种风格,而不是⼀种约束或规则, 过于理想的RESTful API 会付出太多的成本

 RESTful API 缺点:

  • 操作⽅式繁琐, RESTful API通常根据GET, POST, PUT, DELETE 来区分对资源的操作动作. 但是HTTP Method 并不可直接⻅到, 需要通过抓包等⼯具才能观察. 如果把动作放在URL上反⽽更加直观, 更利于团队的理解和交流.
  • ⼀些浏览器对GET, POST之外的请求⽀持不太友好, 需要额外处理.
  • 过分强调资源. ⽽实际业务需求可能⽐较复杂, 并不能单纯使⽤增删改查就能满⾜需求, 强⾏使⽤RESTful API会增加开发难度和成本

所以, 在实际开发中, 如果业务需求和RESTful API不太匹配或者很麻烦时, 也可以不⽤RESTful API. 如果使用场景和REST风格比较匹配, 就可以采用RESTful API.
总之: 无论哪种风格的API, 都是为了⽅便团队开发, 协商以及管理, 不能墨守成规. 尽信书不如无书, 尽信规范不如无规范。

3.4总结 

REST:
想象有一个超级大的 “信息超市”,里面有各种各样的 “商品”,这些 “商品” 就是资源。比如说有水果类的资源(像苹果、香蕉),电器类的资源(像电视、冰箱),REST 就是这个 “信息超市” 里大家都遵守的一套规则,有了它,不管是谁来超市(不管是哪种客户端),也不管超市是谁开的(不管是哪个服务器),大家都能按照统一的方式顺畅地交易 “商品”(交换信息)。 

RESTful:
如果说 REST 是规则,那 RESTful 就是严格遵守这个规则的 “好超市”。这个 “好超市” 里的每一个 “商品” 都有清晰准确的标签(唯一的 URI),工作人员和顾客交流时也完全按照规定的方式来(使用标准 HTTP 方法)。

RESTful 实践:

资源标识:
给每一本书都分配一个独一无二的编号,在网络里就是 URI。比如/books/1 代表编号为 1 的书,这就像给书贴上了专属标签,方便大家查找。

HTTP 方法使用:

  • GET:你在网页上输入/books/1 并发送请求,就像你在书店里跟工作人员说 “我想看看编号为 1 的书的信息”,服务器会返回这本书的详细信息,如书名、作者、价格等。
  • POST:你在网页上填写新书的信息并提交,就像你要把一本新书放到书店里卖。服务器接收到这个请求后,会创建一个新的图书资源。
  • PUT:你发现编号为 1 的书价格写错了,于是修改价格后再次提交,这就像你在书店里把书的价格标签换了。服务器会根据你提供的新信息更新这本书的资源。
  • DELETE:你觉得编号为 1 的书不再需要了,发送一个删除请求,就像你把这本书从书店的货架上拿走了。服务器会把对应的图书资源删除。

现在假设有一个在线书店,我们把它当作一个遵守 REST 规则的 “信息超市” 来实践。

通过这些方式,在线书店就能高效地管理图书信息,并且能和不同的用户(客户端)进行良好的交互,这就是 RESTful 实践.

四.项目存在问题 

  • 远程调⽤时, URL的IP和端⼝号是写死的(http://127.0.0.1:9090/product/), 如果更换IP, 需要修改代
  • 调⽤⽅如何可以不依赖服务提供⽅的IP? 如果多机部署, 如何分摊压⼒?
  • 远程调⽤时, URL非常容易写错, ⽽且复⽤性不⾼, 如何优雅的实现远程调⽤
  • 所有的服务都可以调用该接⼝, 是否有风险?

 微服务架构还面临很多问题, 接下来我们学习如何使用Spring Cloud 来解决这些问题

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

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

相关文章

【Yolov8部署】 VS2019+opencv-dnn CPU环境下部署目标检测模型

文章目录 前言一、导出yolov8模型为onnx文件二、VS2019配置及opencv环境配置三、opencv部署总结 前言 本文主要研究场景为工业场景下&#xff0c;在工控机与工业相机环境中运行的视觉缺陷检测系统&#xff0c;因此本文主要目的为实现c环境下&#xff0c;将yolov8已训练好的检测…

3.30学习总结 Java包装类+高精度算法+查找算法

包装类&#xff1a; 基本数据类型对应的引用数据类型。 基本数据类型&#xff1a;在内存中记录的是真实的值。 八种包装类的父类都是Object类。 对象之间不能直接进行计算。 JDK5之后可以把int和integer看成一个东西&#xff0c;因为会进行内部优化。自动装箱和自动拆箱。 …

3月30号

// 1.toString 返回对象的字符串表示形式Object objnew Object();String str1obj.toString();System.out.println(str1);//java.lang.Objectb4c966a// 核心逻辑: // 当我们打印一个对象的时候,底层会调用对象的toString方法,把对象变成字符串 // 然…

Java——输入,循环,BigInteger,拷贝,排序

读取输入 打印输出到“ 标准输出流”&#xff08;即控制台窗口&#xff09;是一件非常容易的事情&#xff0c;只要 调用System.out.println 即可。然而&#xff0c;读取“ 标准输人流” System.in就没有那么简单了。要想通 过控制台进行输人&#xff0c;首先需要构造一个Scann…

Elasticsearch客户端工具初探--kibana

1 Kibana简介 Kibana是Elastic Stack&#xff08;ELK&#xff09;中的可视化工具&#xff0c;用于对Elasticsearch中存储的数据进行搜索、分析和可视化展示。它提供了直观的Web界面&#xff0c;支持日志分析、业务监控、数据探索等功能&#xff0c;广泛应用于运维监控、安全分析…

ollama在win10安装、使用、卸载

目录 前置&#xff1a; 1 下载ollama 2 安装 3 配置环境变量&#xff0c;设置模型存储位置 4 使用 5 卸载 前置&#xff1a; 1 在打算安装ollama之前&#xff0c;需要先检查电脑当前状态是否能使用ollama。确认条件满足再进行安装操作。 2 https://github.com/ollama/…

查看iphone手机的使用记录-克魔实战

如何查看 iOS 设备近期的详细使用数据 在日常使用手机时&#xff0c;了解设备的运行状态和各项硬件的使用情况可以帮助分析耗电情况、优化应用使用方式。iOS 设备提供了一些数据记录&#xff0c;能够显示应用的启动和关闭时间、后台运行情况&#xff0c;以及应用在使用过程中调…

[Lc5_dfs+floodfill] 简介 | 图像渲染 | 岛屿数量

目录 0.floodfill算法简介 1.图像渲染 题解 2.岛屿数量 题解 之前我们在 bfs 中有介绍过[Lc15_bfsfloodfill] 图像渲染 | 岛屿数量 | 岛屿的最大面积 | 被围绕的区域&#xff0c;现在我们来看看 dfs 又是如何解决的呢 0.floodfill算法简介 floodfill算法又叫洪水灌溉或者…

AI-Sphere-Butler之如何使用腾讯云ASR语音识别服务

环境&#xff1a; AI-Sphere-Butler WSL2 英伟达4070ti 12G Win10 Ubuntu22.04 腾讯云ASR 问题描述&#xff1a; AI-Sphere-Butler之如何使用腾讯云ASR语音识别服务&#xff0c;本地硬件配置不高的情况&#xff0c;建议使用云服务商的ASR 解决方案&#xff1a; 1.登…

Qwen最新多模态大模型:Qwen2.5-Omni介绍与快速入门

一、模型技术突破&#xff1a;重新定义多模态交互 近日&#xff0c;Qwen2.5-Omni正式发布了&#xff01; 这是Qwen系列中全新的旗舰级端到端多模态大模型&#xff0c;专为全面的多模式感知设计&#xff0c;无缝处理包括文本、图像、音频和视频在内的各种输入&#xff0c;同时…

【Golang】第十一弹------反射

&#x1f381;个人主页&#xff1a;星云爱编程 &#x1f50d;所属专栏&#xff1a;【Go】 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 长风破浪会有时&#xff0c;直挂云帆济沧海 目录 1.反射基本介绍 2.反射重要的函数和概念 3.反射应用场景 4.反…

C#里使用libxl的对齐/边框/颜色

一份好的EXCEL文件,通道会有不同的颜色和边框来表示。 以便表示一些重要的信息,这样才能让人们一眼就看到需要关注的信息。 如下面所示: 要显示上面的内容,需要使用下面的例子: private void button12_Click(object sender, EventArgs e){var book = new ExcelBook();if…

软考中级-软件设计师信息安全模块考点解析

一、防火墙技术 内部网络是 安全的可信赖的外部网络是不安全的不可信赖的外部网络和内部网络之间有一个DMZ隔离区&#xff0c; 可以在DMZ隔离区中搭建服务&#xff1a;例如&#xff1a;WEB服务器 安全排序&#xff1a;内网>DMZ>外网 三个发展阶段&#xff1a; 包过滤防…

【蓝桥杯】每日练习 Day 16,17

前言 接下来是这两天的题目&#xff08;昨天主播打完模拟赛感觉身体被掏空所以没有写题目的总结&#xff09;&#xff0c;只有三道题。 一道并查集&#xff0c;一道单调栈和一道单调队列。 奶酪 分析 这是一道模板题&#xff08;连通块&#xff09;&#xff0c;只讲思路。 …

Linux驱动开发--IIC子系统

1.1 简介 I2C 是很常见的一种总线协议&#xff0c; I2C 是 NXP 公司设计的&#xff0c; I2C 使用两条线在主控制器和从机之间进行数据通信。一条是 SCL(串行时钟线)&#xff0c;另外一条是 SDA(串行数据线)&#xff0c;这两条数据线需要接上拉电阻&#xff0c;总线空闲的时候 …

如何应对硬件测试覆盖率不足导致量产故障

硬件测试覆盖率不足导致的量产故障是硬件制造领域的一大痛点。要有效应对&#xff0c;必须从提高测试覆盖率、优化测试方案、引入风险管理机制三个方面入手。其中&#xff0c;优化测试方案尤为关键&#xff0c;应从产品设计阶段开始&#xff0c;通过精确的测试用例规划、详细的…

Centos7 安装 TDengine

Centos7 安装 TDengine 1、简介 官网&#xff1a; https://www.taosdata.com TDengine 是一款开源、高性能、云原生的时序数据库&#xff08;Time Series Database, TSDB&#xff09;, 它专为物联网、车联网、工业互联网、金融、IT 运维等场景优化设计。同时它还带有内建的缓…

Kafka 多线程开发消费者实例

目前&#xff0c;计算机的硬件条件已经大大改善&#xff0c;即使是在普通的笔记本电脑上&#xff0c;多核都已经是标配了&#xff0c;更不用说专业的服务器了。如果跑在强劲服务器机器上的应用程序依然是单线程架构&#xff0c;那实在是有点暴殄天物了。不过&#xff0c;Kafka …

Linux线程池实现

1.线程池实现 全部代码&#xff1a;whb-helloworld/113 1.唤醒线程 一个是唤醒全部线程&#xff0c;一个是唤醒一个线程。 void WakeUpAllThread(){LockGuard lockguard(_mutex);if (_sleepernum)_cond.Broadcast();LOG(LogLevel::INFO) << "唤醒所有的休眠线程&q…

Linux《进程概念(上)》

在之前的Linux学习当中我们已经了解了基本的Linux指令以及基础的开发工具的使用&#xff0c;那么接下来我们就要开始Linux当中一个非常重要的部分的学习——进程&#xff0c;在此进程是我们之后Linux学习的基础&#xff0c;并且通过进程的学习会让我们了解更多的操作系统的相关…