当前位置: 首页 > news >正文

Java学习Day57:碧水金睛兽!(Spring Cloud微服务1.0)

1.微服务入门

(1).单体架构与分布式架构

单体架构: 将业务的所有功能集中在一个项目中开发,打成一个包部署
优点: 架构简单、部署成本低 ; 缺点: 耦合度高
项目打包部署到Tomcat,用户直接访问。用户量增加后就多部署几台服务器形成集群。随着互联网发展、一个APP或Web通常都用有相当多的模块,因此出现了 分布式架构
分布式架构: 根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务。
优点: 降低服务耦合、有利于服务升级拓展 ;

(2).微服务

微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:
单一职责: 微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
面向服务: 微服务对外暴露业务接口
(由于不同模块部署在不同服务器、无法直接调用)
自治: 队独立、技术独立、数据独立、部署独立
隔离性强: 服务调用做好隔离、容错、降级,避免出现级联问题
(避免某个模块宕机造成影响)

单体架构特点?
简单方便,高度耦合,扩展性差,适合小型项目。例如: 学生管理系统

分布式架构特点?
松耦合,扩展性好,但架构复杂,难度大。适合大型互联网项目,例如:京东、淘宝

微服务:一种良好的分布式架构方案
优点: 拆分粒度更小、服务更独立、耦合度更低缺点:架构非常复杂,运维、监控、部署难度提高

2.服务拆分及远程调用

1.不同微服务,不要重复开发相同业务
2.微服务数据独立,不要访问其它微服务的数据库
3.微服务可以将自己的业务暴露为接口,供其它微服务调用
1.基于RestTemplate发起的http请求实现远程调用
2.http请求做远程调用是与语言无关的调用,只要知道对方的ip、端口、接口路径、请求参数即可。

(1).提供者与消费者

服务提供者: 一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
服务消费者: 一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
一个服务既可以是提供者也可以是消费者,要根据具体的业务和情况来判断

我们服务在请求服务的时候,restTemplate访问的地址是固定的。 可在实际开发中通常都会有好几个环境,开发,测试等等环境。每个环境的地址都在变化 因此出现了几个问题:

1.服务消费者该如何获取服务提供者的地址信息?

2.如果有多个服务提供者,消费者该如何选择?

(2).微服务远程调用Demo

在父模块指定了父 POM

<parent><groupId>org.springframework.boot</groupId><version>3.1.0</version><artifactId>spring-boot-starter-parent</artifactId></parent>
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2username: rootpassword: 123456
mybatis:type-aliases-package: com.home.pojoconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplserver:port: 8088

provider实现controller层,services层,和Mapper层,pojo

@RestController
@RequestMapping("/user")
public class userController {@AutowireduserServices userServices;@RequestMapping("/findAll")public usersss findall(){return userServices.findAll();}
}

consumr层只用实现controller层和pojo

@RestController
@RequestMapping("/a")
public class usersssController {@AutowiredRestTemplate restTemplate;@RequestMapping("/b")public usersss findAll(){usersss userssses= restTemplate.getForObject("http://localhost:8088/user/findAll",usersss.class);return userssses;}
}
usersss userssses= restTemplate.getForObject("http://localhost:8088/user/findAll",usersss.class);

3.注册中心 Spring Cloud Eureka

Spirng Cloud Eureka使用Netflix Eureka来实现服务注册与发现(服务治理)。它既包含了服务端组件,也包含了客户端组件,并且服务端与客户端均采用java编写,所以Eureka主要适用于通过java实现的分布式系统,或是JVM兼容语言构建的分布式系统。

Eureka服务端组件:即服务注册中心。它同其他服务注册中心一样,支持高可用配置。依托于强一致性提供良好的服务实例可用性,可以应对多种不同的故障场景。

Eureka客户端组件:主要处理服务的注册和发现。客户端服务通过注册和参数配置的方式,嵌入在客户端应用程序的代码中。在应用程序启动时,Eureka客户端向服务注册中心注册自身提供的服务,并周期性的发送心跳来更新它的服务租约。同时,他也能从服务端查询当前注册的服务信息并把它们缓存到本地,并周期性的刷新服务状态。

注册中心保存提供者提供的服务

客户消费者定期拉去服务列表,需要的话就调用服务提供者,加入IP和端口变化,消费者再拉去一次新的信息即可;

对于注册中心来说,Client和Services都是我的客户端,但是等Client调用Services的时候,Services就是客户端,Client就是服务端;

心跳检测请求是注册中心用来检测服务提供端是否健在的主要依据

1. 整合注册中心Eureka

步骤分三步:

  • 第一步:搭建eureka服务,创建eureka_server工程

  • 第二步:服务提供者provider_service,注册到eureka注册中心

  • 第三步:服务消费者consumer_service,注册到eureka注册中心

4.NACOS

4.1 搭建eureka-server工程

1.创建eureka_server的springboot工程。

2.添加依赖

<properties><spring-cloud.version>2022.0.5</spring-cloud.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><modelVersion>4.0.0</modelVersion><artifactId>eureka_server</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></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></dependencies></dependencyManagement>

3.在启动类EurekaServerApplication声明当前应用为Eureka服务使用@EnableEurekaServer注解

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

4.编写配置文件application.yml

server:port: 8080
spring:application:name: consumer
# 注册中心地址
eureka:client:service-url:defaultZone: http://127.0.0.1:8761/eurekaregistry-fetch-interval-seconds: 30

5.启动EurekaServerApplication

6.测试访问地址http://127.0.0.1:8761,如下信息代表访问成功

4.2 服务提供者-注册到eureka

<properties><spring-cloud.version>2022.0.5</spring-cloud.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<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><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></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></dependencies>
</dependencyManagement>
@SpringBootApplication
@EnableDiscoveryClient
public class springBootProvider {public static void main(String[] args) {SpringApplication.run(springBootProvider.class,args);}
}
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2username: rootpassword: 123456
  application:name: providerServer
mybatis:type-aliases-package: com.home.pojoconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplserver:port: 8088
#配置eureka注册中心的地址
# 注册中心地址
eureka:client:service-url:defaultZone: http://127.0.0.1:8761/eureka
# 租约续约间隔时间,默认30秒eureka:instance:lease-renewal-interval-in-seconds: 30

4.3服务消费者-注册到eureka

<properties><spring-cloud.version>2022.0.5</spring-cloud.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--当前的项目,是eureka的客户端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
</dependencies>
<!--SpringCloud,BOM,依赖清单导入,所有依赖管理的坐标-->
<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></dependencies>
</dependencyManagement>
@SpringBootApplication
@EnableDiscoveryClient
public class springBootConsumerStarter {public static void main(String[] args) {SpringApplication.run(springBootConsumerStarter.class,args);}@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
server:port: 8080
spring:application:name: consumer
# 注册中心地址
eureka:client:service-url:defaultZone: http://127.0.0.1:8761/eurekaregistry-fetch-interval-seconds: 30

4.4消费者通过Eureka访问提供者

@RestController
@RequestMapping("/a")
public class usersssController {@AutowiredRestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@RequestMapping("/b")public usersss findAll(){
//discoveryClient 可以拉取注册中心中服务列表//getInstances(服务名),当前服务只有1个,返回值是List集合,获取0索引服务对象ServiceInstance instance = discoveryClient.getInstances("PROVIDERSERVER").get(0);//instance服务对象的实例。获取服务提供者的IP,端口号String host = instance.getHost();int port = instance.getPort();return restTemplate.getForObject("http://"+host+":"+port+"/user/findAll", usersss.class);}
}

# 租约续约间隔时间,默认30秒
eureka.instance.lease-renewal-interval-in-seconds: 30 

每过30s注册中心查看服务端是否续租

# 每隔多久获取服务中心列表,(只读备份)
eureka.client.registry-fetch-interval-seconds: 30 

每隔30s客户端拉去服务列表

5、SpringCloud Alibaba(Nacos)

5.1 Nacos和Eureka的特点

Eureka的优点包括:

1、简单易用:Eureka框架非常简单易用,便于快速上手和部署。

2、高可用性:Eureka支持多节点部署,并会自动将失效的节点剔除,确保整个系统的高可用性和弹性。

3、动态扩展性:Eureka可以根据实际需求进行扩展,通过添加新的服务提供者可以很容易地增加应用程序的处理能力。

4、易于集成:Eureka可以与Spring Cloud等流行的微服务框架进行无缝集成,从而提供更完善的微服务体系支持。

Eureka的不足之处:

1、Eureka Server 为单点故障问题,虽然可以通过多节点部署来优化和缓解,但是在高并发场景下仍可能成为限制系统扩展的瓶颈。

2、Eureka的服务注册中心本身也需要高可用环境,一旦出现问题,可能影响到整个微服务的正常运行。

Nacos的优点包括:

1、高可用性:Nacos支持多节点部署,通过选举算法实现了高可用和故障转移能力,在节点宕机或网络异常情况下仍能保证整个系统的稳定运行。

2、动态扩展性:Nacos可以根据实际需求进行快速扩展和缩容,支持集群、多数据中心、地域感知等特性。

3、完备的功能支持:Nacos支持服务注册与发现、配置管理、流量管理、DNS解析、存储KV对等功能,并且提供了Web界面和RESTful API等多种方式来使用这些功能。

4、易于集成:Nacos提供了多种语言和框架的集成方案,并且支持Spring Cloud等流行的微服务框架。

总的来说,Nacos是一个功能齐全、易于使用和高可用的分布式服务治理平台,可以为分布式系统提供高效、稳定的运行环境。

5.2 Nacos消费者

使用SpringBoot创建项目,搭建提供者服务(user-service)和消费者服务(consumer-service)。

  1. 创建项目user-service

    1. 执行创建数据库表,sql脚本

    2. 搭建三层架构Mapper、Service、Controller,创建根据id查询用户接口

    3. 配置user-service服务

    4. 启动2个端口9091、9092服务,并测试服务user-service

  2. 创建项目consumer-service

    1. 配置RestTemplate对象,注入Spring容器

    2. 搭建service层和controller层,通过RestTemplate对象发送请求访问提供者接口

    3. 测试消费者服务consumer-service

        <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
 <!--SpringCloud,BOM,依赖清单导入,所有依赖管理的坐标--><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>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring.cloud.alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
@RestController
@RequestMapping("user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("queryUserById")public User queryUserById(Integer id){return userService.queryUserById(id);}
}
@Service
public class UserServiceImpl implements UserService{@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@Overridepublic User queryUserById(Integer id) {List<ServiceInstance> instances = discoveryClient.getInstances("provider_user");ServiceInstance serviceInstance = instances.get(0);String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort();System.out.println("url = " + "http://"+url);User user = restTemplate.getForObject(url+"/user/queryUserById?id=" + id, User.class);return user;}
}
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2username: rootpassword: 123456application:name: providerNacoscloud:nacos:discovery:server-addr: 127.0.0.1:8848
mybatis:type-aliases-package: com.home.pojoconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

5.3 Nacos服务者

<properties><spring-cloud.version>2022.0.5</spring-cloud.version><spring.cloud.alibaba.version>2022.0.0.0</spring.cloud.alibaba.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@RestController
@RequestMapping("/a")
public class usersssController {@AutowiredRestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@RequestMapping("/b/{id}")public usersss findAll(@PathVariable("id") Integer id){
//discoveryClient 可以拉取注册中心中服务列表//getInstances(服务名),当前服务只有1个,返回值是List集合,获取0索引服务对象
//        ServiceInstance instance = discoveryClient.getInstances("providerNacos").get(0);//instance服务对象的实例。获取服务提供者的IP,端口号
//        String host = instance.getHost();
//        int port = instance.getPort();return restTemplate.getForObject("http://providerNacos/user/findAll/"+id, usersss.class);}
}
server:port: 8080
spring:application:name: consumerNacos
# 注册中心地址cloud:nacos:discovery:server-addr: 127.0.0.1:8848

6.负载均衡

将任务均匀分配

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

server:
  port: ${port:9091}

构建集群

@RestController
@RequestMapping("/user")
public class userController {@Autowiredhome.services.userServices userServices;@Value("${server.port}")private Integer port;@GetMapping("/findAll/{id}")public usersss findall(@PathVariable("id") Integer id){usersss usersss1= userServices.findAll(id);usersss1.setPort(port);return usersss1;}
}

6.1 修改负责均衡算法

public class CustomLoadBalancerConfiguration {
    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

 @Configuration
    @LoadBalancerClients(value = {
            @LoadBalancerClient(name = "providerUser" , configuration = CustomLoadBalancerConfiguration.class)      // 将负载均衡算法应用到指定的服务提供方中
    })
    public class RestTemplateConfiguration {

        @Bean
        @LoadBalanced       // 让RestTemplate具有负载均衡的能力
        public RestTemplate restTemplate() {
            return new RestTemplate() ;
        }
}

负载均衡算法可以改变调用顺序;

相关文章:

Java学习Day57:碧水金睛兽!(Spring Cloud微服务1.0)

1.微服务入门 (1).单体架构与分布式架构 单体架构&#xff1a; 将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署优点&#xff1a; 架构简单、部署成本低 &#xff1b; 缺点&#xff1a; 耦合度高项目打包部署到Tomcat&#xff0c;用户直接访问。用户量增加后…...

物联网开发教程专栏介绍与专栏说明——列表目录查阅(持续更新)

阿齐Archie《物联网开发&#xff1a;完整实现单片机通信模组云服务器智能应用软件》专栏 为方便查阅学习本专栏&#xff0c;特整理专栏介绍与专栏说明 一、专栏介绍 物联网开发教程专栏目前有P1和P2系列&#xff0c;P1系列为《手把手完整实现STM32ESP8266MQTT阿里云APP应用》…...

uni-app实现app展示进度条在线更新以及定时更新提醒

需求&#xff1a;需要在app启动后进行检查更新&#xff0c;如果有更新就提示更新&#xff0c;可以点击确定更新或者暂时不更新&#xff0c;如果不更新&#xff0c;就将当前的时间进行缓存&#xff0c;并且再次进入时进行对比&#xff0c;只要超过一天时间就继续提醒检查更新 第…...

【Linux】进程间通信(命名管道、共享内存、消息队列、信号量)

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;Linux 创作时间 &#xff1a;2024年11月2日 命名管道&#xff1a; 如果我们想在不相关的进程之间交换数据&#xff0c;可以使用FIFO文件来做这项工作&#xff0c;它经常被称为命名管道。命名管道是一种特殊类型的文…...

[Android]从FLAG_SECURE禁止截屏看surface

在应用中&#xff0c;设置activity的flag为FLAG_SECURE就可以禁止截屏&#xff0c;截屏出来是黑色的&#xff0c; 试验一下&#xff0c; 注意事项 影响&#xff1a; 设置 FLAG_SECURE 标志后&#xff0c;用户将无法对该Activity进行截屏或录制屏幕。这个标志会影响所有屏幕录…...

python 五子棋小游戏

1. 实现效果 Python五子棋小游戏 2. 游戏规则 规则说明&#xff0c;五子棋人机对战游戏规则如下&#xff1a;‌ Ⅰ 默认规则 - 五子棋规则 对局双方‌&#xff1a;各执一色棋子&#xff0c;一方持黑色棋子&#xff0c;另一方持白色棋子。棋盘与开局‌&#xff1a;空棋盘开局…...

JeecgBoot集成工作流实战教程

Activiti是一个轻量级的工作流程和业务流程管理&#xff08;BPM&#xff09;平台&#xff0c;它主要面向业务人员、开发人员和系统管理员。这个平台的核心是一个快速且可靠的Java BPMN 2流程引擎。Activiti是开源的&#xff0c;并且基于Apache许可证进行分发。它可以运行在任何…...

第三十章 章节练习商品列表组件封装

目录 一、需求说明 二、技术要点 三、完整代码 3.1. main.js 3.2. App.vue 3.3. MyTable.vue 3.4. MyTag.vue 一、需求说明 1. my-tag 标签组件封装 (1) 双击显示输入框&#xff0c;输入框获取焦点 (2) 失去焦点&#xff0c;隐藏输入框 (3) 回显标签信息 (4) 内…...

NumPy 高级索引

NumPy 高级索引 NumPy 是 Python 中用于科学计算的核心库之一,它提供了一个强大的N维数组对象和许多用于操作这些数组的函数。在 NumPy 中,除了基本的索引和切片操作外,还提供了高级索引功能,这使得您可以以更加灵活和高效的方式访问和操作数组中的数据。本文将详细介绍 N…...

C/C++常用编译工具链:GCC,Clang

目录 GNU Compiler Collection GCC的优势 编译产生的中间文件 Clang Clang的特点 什么是LLVM&#xff1f; Clang编译过程中产生的中间表示文件 关于Clang的调试 C 编译工具链中有几个主要的编译工具&#xff0c;包括&#xff1a; GNU Compiler Collection (GCC…...

let和war的区别

let和war的区别 看不懂图片&#xff0c;可以看视频教程...

[CUDA] stream使用笔记

文章目录 1. stream一般用法2. stream与event&#xff1a;3. stream异常的排查4. stream的异步与同步行为 1. stream一般用法 cudaStream_t stream_; cudaStreamCreate(&stream_); // create stream // some operators running on this stream_ cudaStreamSynchronize(str…...

第二课:开发工具

在本课中&#xff0c;我们将介绍一些常用的C开发工具&#xff0c;并附上下载链接&#xff0c;帮助你选择合适的工具进行开发。 1. DEVC DEVC 是一个轻量级的C开发工具&#xff0c;适合初学者使用。它提供了基本的代码编辑、编译和调试功能。 下载链接: DEVC 下载 2. Visual…...

Vue 学习随笔系列十三 -- ElementUI 表格合并单元格

ElementUI 表格合并单元格 文章目录 ElementUI 表格合并单元格[TOC](文章目录)一、表头合并二、单元格合并1、示例代码2、示例效果 一、表头合并 参考&#xff1a; https://www.jianshu.com/p/2befeb356a31 二、单元格合并 1、示例代码 <template><div><el-…...

对于一个含有直流和交流分量的信号,如何使用示波器正确显示并测出直流电压值和交流电压峰峰值?

对于一个含有直流&#xff08;DC&#xff09;和交流&#xff08;AC&#xff09;分量的混合信号&#xff0c;使用示波器来正确显示和测量其直流电压值和交流电压峰峰值需要选择适当的设置和方法。以下是详细的步骤&#xff1a; 所需设备 示波器电压探头 步骤一&#xff1a;连…...

移动混合开发面试题及参考答案

目录 什么是混合开发(Hybrid App)? 混合开发(Hybrid App)与原生开发相比有什么优缺点? 优点 缺点 混合开发(Hybrid App)的兴起原因是什么? 市场竞争和成本控制需求 技术发展和资源整合 人才资源的考量 Web App、Native App 和混合开发(Hybrid App)的区别是…...

命令行工具开发秘籍:从零开始创建实用Python脚本(如何创建Python命令行工具)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 创建命令行工具的基础🔖 在非模块化的环境中🔖 在模块化环境中📝 打包和安装模块📝 使用命令行工具⚓️ 相关链接 ⚓️📖 介绍 📖 如何将自己的Python模块打包成一个可在命令行中直接执行的工具?…...

Python - PDF 分割成单页、PDF 转图片(PNG)

文章目录 PDF 分割成一页页的 PDFPDF 转 PNGPDF 分割成一页页的 PDF import fitz def split_pdf(pdf_path, save_dir):source_pdf = fitz.open(pdf_path)# 遍历source_pdf中的每一页,page_number从0开始计数 for idx...

【网络】套接字编程——TCP通信

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;TCP网络服务器简单模拟实现。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! > 专栏选自&#xff1a;…...

PyTorch实践-CNN-验证码识别

1 需求 GitHub - xhh890921/cnn-captcha-pytorch: 小黑黑讲AI&#xff0c;AI实战项目《验证码识别》 2 接口 含义 在optim.Adam接口中&#xff0c;lr参数代表学习率&#xff08;Learning Rate&#xff09;。学习率是优化算法中的一个关键超参数&#xff0c;它决定了在每次迭代…...

Cadence启动文件背后的设计哲学:为什么.cdsinit总覆盖不了.cdsenv的设置?

Cadence启动文件背后的设计哲学&#xff1a;为什么.cdsinit总覆盖不了.cdsenv的设置&#xff1f; 当你在Cadence Virtuoso中反复调整波形显示参数&#xff0c;却发现每次重启后设置都被重置时&#xff0c;背后隐藏的是一套精妙的EDA工具配置体系。这个看似简单的"设置失效…...

反激式电源设计避坑指南:如何优化5V/2A方案的EMI和效率

反激式电源设计避坑指南&#xff1a;如何优化5V/2A方案的EMI和效率 在中小功率电源设计中&#xff0c;反激式拓扑凭借结构简单、成本低廉的优势占据主流地位。但当工程师面对5V/2A这类常见规格时&#xff0c;往往会陷入效率卡在65%难以提升、EMI测试屡次失败的困境。本文将从实…...

太原理工大学Web开发历年真题解析:期末复习必备指南(附最新试卷)

太原理工大学Web开发核心考点深度剖析与高效复习方法论 Web开发课程期末备考的战略视角 又到了期末季&#xff0c;作为太原理工大学计算机相关专业的学生&#xff0c;面对Web开发这门实践性极强的课程&#xff0c;你是否还在为如何高效复习而焦虑&#xff1f;不同于传统理论课…...

Cursor省钱神器:interactive-feedback-mcp安装配置全攻略(附常见问题排查)

Cursor省钱神器&#xff1a;interactive-feedback-mcp安装配置全攻略&#xff08;附常见问题排查&#xff09; 在AI辅助编程领域&#xff0c;Cursor凭借其强大的代码生成和智能补全功能&#xff0c;已成为开发者日常工作的得力助手。然而&#xff0c;许多用户在使用过程中常常…...

FreeRTOS内核探秘:双向链表如何玩转任务调度?从xListEnd到pxIndex全解析

FreeRTOS内核探秘&#xff1a;双向链表如何玩转任务调度&#xff1f;从xListEnd到pxIndex全解析 在嵌入式实时操作系统领域&#xff0c;任务调度效率直接决定了系统响应能力。FreeRTOS作为市场占有率最高的RTOS之一&#xff0c;其精巧的内核设计一直是开发者研究的焦点。想象一…...

终极Node.js无头浏览器测试指南:Zombie.js与Mocha集成实战

终极Node.js无头浏览器测试指南&#xff1a;Zombie.js与Mocha集成实战 【免费下载链接】zombie Insanely fast, full-stack, headless browser testing using node.js 项目地址: https://gitcode.com/gh_mirrors/zo/zombie 在当今快速发展的Web开发领域&#xff0c;Zomb…...

AI头像生成器新手教程:5个常用风格关键词+3类背景模板Prompt速查表

AI头像生成器新手教程&#xff1a;5个常用风格关键词3类背景模板Prompt速查表 1. 快速了解AI头像生成器 AI头像生成器是一个帮你设计专属头像创意的智能工具。你只需要简单描述想要的头像风格&#xff0c;它就能生成详细的描述文案&#xff0c;这些文案可以直接用在Midjourne…...

别再瞎猜了!手把手教你用公式算清摄像头MIPI Lane数(附Excel计算器)

摄像头MIPI Lane数计算实战&#xff1a;从理论到Excel工具全解析 在嵌入式摄像头模组开发中&#xff0c;MIPI Lane数的选择往往让工程师陷入两难&#xff1a;Lane数不足会导致数据吞吐瓶颈&#xff0c;而过度配置又会增加功耗和成本。我曾见过一个团队因为凭经验选择了2 Lane配…...

从基础到卓越:Mac Mouse Fix的技术演进与用户价值提升之路

从基础到卓越&#xff1a;Mac Mouse Fix的技术演进与用户价值提升之路 【免费下载链接】mac-mouse-fix Mac Mouse Fix - A simple way to make your mouse better. 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 解决鼠标体验痛点&#xff1a;从功能…...

组合导航(五):惯性导航系统的误差分析与校正方法

1. 惯性导航系统误差的根源剖析 刚接触惯性导航的朋友们常会遇到这样的困惑&#xff1a;为什么同样的设备&#xff0c;在不同环境下定位精度差异这么大&#xff1f;这就像用同一把尺子测量物体&#xff0c;有时准有时不准&#xff0c;问题往往出在尺子本身的误差上。惯性导航系…...