旧服务改造及微服务架构演进

news2025/1/7 13:52:44

旧服务改造及微服务架构演进

    • 微服务架构演进
      • 1.微服务架构
      • 2.微服务架构的特点
      • 3.单体架构与微服务架构之间的对比
      • 4.微服务架构演进历程
    • 旧服务改造
      • 1. 微服务拆分的一些通用原则
      • 2.微服务拆分策略
        • (1)功能维度拆分策略
        • (2)非功能维度拆分策略
      • 3.旧服务改造演示
        • (1)Spring Cloud Alibaba技术栈选型
        • (2)接入Nacos注册中心
        • (3)接入nacos配置中心
        • (4)接入openfeign实现服务之间的通信
    • 总结

微服务架构演进

1.微服务架构

微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用 HTTP 资源 API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的数据存储技术。 --摘录总结自文章微服务架构讲解有兴趣可以去查看原文。
在这里插入图片描述

2.微服务架构的特点

微服务架构是一种将单体应用程序拆分成多个小型、独立的服务的架构风格,每个服务都可以独立开发、部署和扩展。其具有以下特点:

  • 低耦合高内聚

​ 微服务之间通过轻量级的通信机制进行交互,如 RESTful API、消息队列等,它们之间的依赖关系非常松散。一个微服务的内部实现细节对其他微服务是透明的,当一个微服务发生变化时,只要其接口不变,就不会对其他微服务产生影响。而每个微服务都专注于完成一项特定的业务功能,将相关的业务逻辑和数据处理都封装在内部,具有高度的内聚性。

  • 易拓展和易维护

​ 由于每个微服务的功能相对单一、代码规模较小,结构也相对简单,开发人员能够更快速地理解和掌握其业务逻辑和代码逻辑,降低了维护的难度。当业务需求发生变化或需要添加新功能时,可以很容易地通过增加新的微服务或对现有微服务进行扩展来实现,能够快速响应业务的变化,满足不断增长的业务需求。

  • 跨语言开发

由于各个微服务之间通过轻量级的通信机制进行交互,那么就不要求各个微服务编写语言需要一致,只需要遵守对应的通信规则,在需要别的微服务信息能够正确获取即可。

  • 独立部署和弹性扩容

​ 每个微服务都可以独立进行部署,无需依赖其他服务的部署过程。这意味着当某个微服务需要更新或修改时,只需单独部署该服务,而不会影响到其他微服务的正常运行,大大提高了部署的效率和灵活性。并且我们可以根据每个微服务的实际负载情况,独立地进行水平扩展或收缩。比如,在电商促销活动期间,订单处理微服务可以自动增加实例数量以应对高并发,而商品展示微服务如果负载没有明显变化,则无需进行扩展。

3.单体架构与微服务架构之间的对比

在这里插入图片描述

4.微服务架构演进历程

第一代微服务架构

在第一代微服务架构中,以 RPC 通信为代表,首要解决的是微服务之间的通信问题。技术框架代表如阿里 Dubbo,跨语言平台的框架 Thrift、gRPC…在这个阶段,我们网关逻辑、服务注册与发现逻辑、负载均衡等等都需要我们自己实现,由于我们分成多个服务开发,那么我们在每个服务上都要实现上面这些功能,这样就需要大量的代码逻辑需要实现,所以这个阶段我们主要解决了服务之间通信的问题。

在这里插入图片描述

第二代微服务架构

在第二代微服务架构中,更多就是将一些相同逻辑,如服务的自动注册和发现,服务之间的通信以及容错机制模块化,将他们封装为不同的SDK或者插件或者服务框架,让我们在使用过程中只需要引入相关依赖,配置一些属性就能够使用,并且将这些非业务逻辑与业务逻辑分离开,这也是我们现阶段主流的微服务架构。这个阶段比较有代表性的框架如 Dubbo、Spring Cloud,只需要少量代码和注解,即可集成各种所需的服务治理能力。但随着服务框架内功能日益繁多,复用不同开发语言的基础功能就会十分苦难,比如去调用go、python有点困难,这也意味着微服务的开发人员被迫绑定在某种特定语言之下,从而违背了微服务敏捷迭代的原则。还有个最重要的问题,就是版本冲突的问题,比如我们开发中必须注意springcloud、springcloud alibaba springboot之间的版本,不然的话可能版本不兼容导致各种各样的异常。

在这里插入图片描述

第三代微服务架构

随着云原生时代的到来,第三代微服务架构也随之推出,在这个阶段出现了服务网格的概念。原来被模块化到服务框架的微服务基础能力,从一个 SDK 演进成为一个独立的进程 - Sidecar(边车)。开发人员只要关注业务逻辑的开发,由边车进程开始接管微服务应用之间的流量,承载第二代微服务架构中服务框架的功能,包括如服务发现、调用容错以及服务治理能力,具体如权重路由、灰度路由、流量重放等。这个变化使得第二代架构中多语言支持问题得到了彻底解决,服务A跟服务B之间的语言可以使用不同的语言,因为服务之间的通信由边车实现。

这个阶段比较有代表性的框架如 Linkerd、Istio 等,可以着重了解一下Istio ,这里不着重讲解,可以去 官网查看,未来是云原生的时代,建议大家多去了解一下这方面。

在这里插入图片描述

第四代微服务架构

第四代微服务架构是目前业界提出的多运行时微服务架构,利用最近的 FaaS 和 AWS 的 Lambda 等无服务器技术来进一步简化微服务的开发和交付。

在第四代微服务架构中,微服务由一个应用进一步简化为微逻辑(Micrologic),变成短暂的功能的集合。就是我们业务中的API也即是controller层的方法变成一个服务进行开发。这新型的架构也对边车模式提出了更高的要求,更多可复用的分布式能力从应用中剥离,并下沉到边车中,例如状态管理、资源绑定、链路追踪、事务管理等。同时,开发侧开始提倡面向 localhost 编程的理念,并提供标准 API 屏蔽底层资源、服务、基础设施之间的差异,以进一步降低微服务的开发难度。

目前比较有代表性的框架如 Dapr,万物皆API。

在这里插入图片描述

旧服务改造

1. 微服务拆分的一些通用原则

单一服务功能高内聚低耦合:每个服务只完成自己职责内的任务,对于不是自己职责的功能交给其它服务来完成

闭包原则:当我们需要改变一个微服务的时候,所有依赖都在这个微服务的组件内,不需要修改其他微服务

服务自治、接口隔离原则:尽量消除对其他服务的强依赖,这样可以降低沟通成本,提升服务稳定性。服务通过标准的接口隔离,隐藏内部实现细节。这使得服务可以独立开发、测试、部署、运行,以服务为单位持续交付。

持续演进原则:在服务拆分的初期,你其实很难确定服务究竟要拆成什么样。应逐步划分,持续演进,避免服务数量的爆炸性增长。

**拆分的过程尽量避免影响产品的日常功能迭代:**也就是说要一边做产品功能迭代,一边完成服务化拆分。比如优先剥离比较独立的边界服务(如短信服务等),从非核心的服务出发减少拆分对现有业务的影响。同时当两个服务存在依赖关系时优先拆分被依赖的服务。

服务接口的定义要具备可扩展性:比如微服务的接口因为升级把之前的三个参数改成了四个,上线后导致调用方大量报错,推荐做法服务接口的参数类型最好是封装类,这样如果增加参数就不必变更接口的签名

避免环形依赖与双向依赖:尽量不要有服务之间的环形依赖或双向依赖,原因是存在这种情况说明我们的功能边界没有化分清楚或者有通用的功能没有下沉下来。

在这里插入图片描述

**阶段性合并:**随着你对业务领域理解的逐渐深入或者业务本身逻辑发生了比较大的变化,亦或者之前的拆分没有考虑的很清楚,导致拆分后的服务边界变得越来越混乱,这时就要重新梳理领域边界,不断纠正拆分的合理性。

**自动化驱动:**部署和运维的成本会随着服务的增多呈指数级增长,每个服务都需要部署、监控、日志分析等运维工作,成本会显著提升。因此,在服务划分之前,应该首先构建自动化的工具及环境。开发人员应该以自动化为驱动力,简化服务在创建、开发、测试、部署、运维上的重复性工作,通过工具实现更可靠的操作,避免微服务数量增多带来的开发、管理复杂度问题。

2.微服务拆分策略

(1)功能维度拆分策略

大的原则是基于业务复杂度拆分服务: 业务复杂度足够高,应该基于领域驱动拆分服务。业务复杂度较低,选择基于数据驱动拆分服务

  • 基于数据驱动拆分服务: 从需求以及数据库角度触发,自下而上的架构设计方法,通过分析需求,确定整体数据结构,根据表之间的关系拆分服务。

​ 拆分步骤: 需求分析,抽象数据结构,划分服务,确定调用关系和业务流程验证。

  • 基于领域驱动拆分服务: 从业务模块开始划分,明确自己业务需求可以划分为几个微服务。自上而下的架构设计方法,通过对需求不断探讨,借鉴其他类似产品业务功能,确定关键业务场景,逐步确定边界上下文。领域驱动更强调业务实现效果,认为自下而上的设计可能会导致技术人员不能更好地理解业务方向,进而偏离业务目标。

​ 拆分步骤:通过模型和领域专家建立统一语言,业务分析,寻找聚合,确定服务调用关系,业务流程验证和持续优化。

​ 以电商的场景为例,交易链路划分的限界上下文如下图左半部分,根据一个限界上下文可以设计一个微服务,拆解出来的微服务如下 图右侧部分。

在这里插入图片描述

  • 还有一种常见拆分场景,从已有单体架构中逐步拆分服务。

拆分步骤: 前后端分离,提取公共基础服务(如授权服务,分布式ID服务),不断从老系统抽取服务,垂直划分优先,适当水平切分

以上几种拆分方式不是多选一,而是可以根据实际情况自由排列组合。同时拆分不仅仅是架构上的调整,也意味着要在组织结构上做出相应的适应性优化,以确保拆分后的服务由相对独立的团队负责维护。

(2)非功能维度拆分策略

主要考虑六点包括扩展性、复用性、高性能、高可用、安全性、异构性

扩展性

区分系统中变与不变的部分,不变的部分一般是成熟的、通用的服务功能,变的部分一般是改动比较多、满足业务迭代扩展性需要的功能,我们可以将不变的部分拆分出来,作为共用的服务,将变的部分独立出来满足个性化扩展需要

同时根据二八原则,系统中经常变动的部分大约只占 20%,而剩下的 80% 基本不变或极少变化,这样的拆分也解决了发布频率过多而影响成熟服务稳定性的问题。

复用性

不同的业务里或服务里经常会出现重复的功能拆分出来形成独立的服务。

高性能

将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其它服务。

我们也可以基于读写分离来拆分,比如电商的商品信息,在 App 端主要是商品详情有大量的读取操作,但是写入端商家中心访问量确很少。因此可以对流量较大或较为核心的服务做读写分离,拆分为两个服务发布,一个负责读,另外一个负责写。

数据一致性是另一个基于性能维度拆分需要考虑的点,对于强一致的数据,属于强耦合,尽量放在同一个服务中(但是有时会因为各种原因需要进行拆分,那就需要有响应的机制进行保证),弱一致性通常可以拆分为不同的服务。

高可用

将可靠性要求高的核心服务和可靠性要求低的非核心服务拆分开来,然后重点保证核心服务的高可用。

安全性

不同的服务可能对信息安全有不同的要求,因此把需要高度安全的服务拆分出来,进行区别部署,比如设置特定的 DMZ 区域对服务进行分区部署,可以更有针对性地满足信息安全的要求,也可以降低对防火墙等安全设备吞吐量、并发性等方面的要求,降低成本,提高效率。

异构性

对于对开发语言种类有要求的业务场景,可以用不同的语言将其功能独立出来实现一个独立服务。

3.旧服务改造演示

这里拿我之前的一个项目演示,感兴趣的可以去gitee查看项目代码
在这里插入图片描述

shouyiLibrary-auth-server 认证微服务

shouyiLibrary-cart 购物车微服务

shouyiLibrary-common 通用微服务

shouyiLibrary-coupon 优惠劵微服务

shouyiLibrary-gateway 网关微服务

shouyiLibrary-member 会员微服务

shouyiLibrary-order 订单微服务

shouyiLibrary-product 商品微服务

shouyiLibrary-search 检索微服务

shouyiLibrary-seckill 秒杀微服务

shouyiLibrary-third-party 第三方微服务

shouyiLibrary-ware 库存微服务

这里我会以shouyiLibrary-member来演示如何接入微服务Spring Cloud&Spring Cloud Alibaba技术栈。

(1)Spring Cloud Alibaba技术栈选型

Spring Cloud Alibaba官网:https://github.com/alibaba/spring-cloud-alibaba/wiki

SpringCloud的几大痛点:

  • SpringCloud部分组件停止维护和更新,给开发带来不便;
  • SpringCloud部分环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
  • SpringCloud配置复杂,难以上手,部分配置差别难以区分和合理应用

SpringCloud Alibaba的优势:

  • 阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用成套的产品搭配完善的可视化界面给开发运维带来极大的便利
  • 搭建简单,学习曲线低。

所以我们优先选择Spring Cloud Alibaba提供的微服务组件

按照Spring Cloud Alibaba官方推荐版本选择对应的Spring Cloud、Spring Cloud Alibaba、springboot的版本版本对照说明

在这里插入图片描述

(2)接入Nacos注册中心

在这里插入图片描述

微服务之间通信首先需要知道各个微服务之间的ip以及端口信息,这就需要我们将微服务的一些信息注册到某个地方,让其他微服务能够知道自己服务的地址,能够正确的调用,所以我们就需要一个注册中心来实现服务的注册与发现,这里我们使用nacos作为我们的注册中心。

第一步:引入依赖

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

第二步:在yml中填写注册中心地址以及信息

spring:
  application:
    name: shouyiLibrary-member #服务名
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848  #注册中心地址

第三步,在启动类上加上服务发现注解

@EnableDiscoveryClient

此时我们启动程序加nacos,如果能够在nacos上看到服务的信息,就表示服务的注册与发现成功

在这里插入图片描述

(3)接入nacos配置中心

随着微服务数量的增多,如果部署到生产环境中,修改配置特别的麻烦,比如我们想要改一个端口,结果需要下线,修改,再上线,可以看到这种非常的麻烦而且效率非常低,而且在我们配置文件中存在许多重复的配置,如日志等等,此时我们就希望有一个集中管理配置的地方,最好还能实现热部署,此时我们就需要引入配置中心,这里我们使用nacos作为我们的配置中心。

第一步:引入依赖

<!--        nacos配置管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

第二步:在yml中填写注册中心地址以及信息

spring:
  application:
    name: shouyiLibrary-member #服务名
    cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      config: #配置文件相关配置
        namespace: dev01
        group: shouyiLibrary-member
        file-extension: yaml
        refresh-enabled: true
        #最终会到我们的注册中心找到 shouyiLibrary-member.yaml
            #共享配置
        shared-configs:
          - data-id: swagger-${spring.profiles.active}.yaml
            group: shouyiLibrary--common
            refresh: true
          - data-id: logging-${spring.profiles.active}.yaml
            group: shouyiLibrary--common
            refresh: true
          - data-id: freemarker-config-dev.yaml
            group: shouyiLibrary--common
            refresh: true
          - data-id: feign-${spring.profiles.active}.yaml
            group: shouyiLibrary--common
            refresh: true
  profiles:
    active: dev   #环境名

我们就可以将我们服务的配置信息移到nacos上,这样启动微服务就会到nacos上找我们的配置信息。

在这里插入图片描述

(4)接入openfeign实现服务之间的通信

接下来就是解决微服务之间通信的问题,不多说直接开始。

第一步:引入依赖

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

第二步:在启动类上说明远程调用类的位置,

@EnableFeignClients(basePackages = "com.uliky.shouyiLibrary.member.feign")

第三步:在com.uliky.shouyiLibrary.member.feign创建类,并在类上添加FeignClient注解,并声明该微服务在nacos上的服务名,最后将该服务中需要的方法原封不动拷贝过来即可完成调用。

@FeignClient("shouyiLibrary-order")
public interface OrderFeignService {
    /**
     * 分页查询当前登录用户的所有订单信息
     * @param params
     * @return
     */
    @PostMapping("/order/order/listWithItem")
    R listWithItem(@RequestBody Map<String, Object> params);

}

扩展场景:实现 RequestInterceptor,添加请求头参数用于传递 memberId

我们有可能会遇到一些方法需要在请求头中拿到一个字段,如id用来去数据库中查询,这个时候我们就需要实现 RequestInterceptor来在发送请求之前,往请求头上插入数据,如:

public class HeaderInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if(null != attributes){
        	HttpServletRequest request = attributes.getRequest();
        	log.info("从 Request 中解析请求头");
        	template.header("memberId",request.getHeader("memberId"));
        }
    }
}
# FeignConfig.java 中添加拦截器配置
@Bean
public RequestInterceptor requestInterceptor() {
	return new HeaderInterceptor();
}

(5)接入gateway网关

第一步:引入依赖

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

第二步:在配置文件中配置路由规则

注意,gateway网关也需要注册到nacos中

spring:
  cloud:
    gateway:
      routes:   #路由规则
        - id: product_route  #给路由起名字,可以随意取
          uri: lb://gulimall-product //转发到哪个微服务上,lb:表示负载均衡
          predicates:
            - Path=/api/product/**,/hello	//路由规则,/api/product/开头的请求,多个路由规则由","隔开
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment}	//过滤,对接收的请求格式进行处理,再发到后端服务器。
        - id: coupon_route
          uri: lb://gulimall-coupon
          predicates:
            - Path=/api/coupon/**,/hello
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment}

到此微服务就改造的差不多了,但是这只是最基本的服务改造,还需要根据你的业务需求引入其他的微服务组件,比如负载均衡、熔断机制等等,分布式事务等等,大致都跟上述差不多,所以这里就不再演示。

总结

本篇博客内容主要讲解了微服务架构的演进以及旧服务改造,讲述了微服务架构的优势以及未来微服务发展趋势,大家可以通过查阅资料进行相关的学习,抓住未来云原生的机遇,最后希望大家能够留下点赞、关注、收藏,让我能够继续发表更多文章。

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

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

相关文章

Science Robotics让软机器人“活”得更久的3D打印!

软机器人硬件在医疗、探索无结构环境等领域有广泛应用&#xff0c;但其生命周期有限&#xff0c;导致资源浪费和可持续性差。软机器人结合软硬组件&#xff0c;复杂组装和拆卸流程使其难以维修和升级。因此&#xff0c;如何延长软机器人的生命周期并提高其可持续性成为亟待解决…

MyBatis执行一条sql语句的流程(源码解析)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 MyBatis执行一条sql语句的流程&#xff08;源码解析&#xff09; MyBatis执行sql语句的流程加载配置文件加载配置文件的流程 创建sqlsessionFactory对象解析Mapper创建sqlses…

Git命令行的使用

目录 一、什么是Git 1、本地仓库 vs 远端仓库 本地仓库 远端仓库 2、.git vs .gitignore .git .gitignore 二、使用Git命令 1、安装git 2、git首次使用需要配置用户邮箱和用户名 3、上传目录/文件到远端仓库步骤 1&#xff09;创建放置文件的目录 2&#xff09;cd…

法律专业legal case的留学论文写作技巧分析(1)

对于法律专业的留学生而言&#xff0c;案例的分析是写作的重要方面。无论留学的国家是英、美、澳洲还是加拿大&#xff0c;它们都属于case law 的法律体系。一个非常显著的特点便是通过对案例进行分析和提炼&#xff0c;从中总结提炼出principle和rules。case analysis的留学论…

一文理解区块链

一文搞懂区块链 区块链的诞生&#xff0c;源于对 电子货币&#xff08;e-money&#xff09; 的探索需求&#xff0c;即Bitcoin的产生。因此&#xff0c;了解的小伙伴应该知道区块链的常见定义是&#xff1a;不可篡改的分布式账本。 为什么发明“账本”&#xff0c;而不是直接发…

C 实现植物大战僵尸(四)

C 实现植物大战僵尸&#xff08;四&#xff09; 音频稍卡顿问题&#xff0c;用了 SFML 三方库已优化解决 安装 SFML 资源下载 https://www.sfml-dev.org/download/sfml/2.6.2/ C 实现植物大战僵尸&#xff0c;完结撒花&#xff08;还有个音频稍卡顿的性能问题&#xff0c;待…

编程入门(2)-2024年 RAD Studio version 12发布综述

随着2024年即将画上句号&#xff0c;我想借此机会回顾一下我们在这一年中发布的一些Embarcadero产品、行业趋势&#xff0c;并感谢我们尊贵的客户们对我们的产品一如既往的支持。这一年对我们来说充满了激动人心的变化和发展&#xff0c;我们非常高兴能与您一起踏上这段旅程。 …

[Day 12]904.水果成篮

今天给带来的题目是滑动窗口的另一种题目&#xff0c;之前我们讲了滑动窗口题目中长度最小的子数组&#xff0c;今天这个题目实际上是求长度最长的子数组 题目描述&#xff1a;力扣链接 904.水果成篮 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整…

SpringBoot 2.6 集成es 7.17

引言 在现代应用开发中&#xff0c;Elasticsearch作为一个强大的搜索引擎和分析引擎&#xff0c;已经成为许多项目不可或缺的一部分。Spring Boot作为Java生态中最受欢迎的微服务框架之一&#xff0c;其对Elasticsearch的支持自然也是开发者关注的焦点。本文将详细介绍如何在S…

【数据仓库】hive on Tez配置

hive on Tez 搭建 前提是hive4.0hadoop3.2.2数仓已搭建完成&#xff0c;现在只是更换其执行引擎 为Tez。搭建可参考【数据仓库】hive hadoop数仓搭建实践文章。 Tez 下载 下载地址 https://archive.apache.org/dist/tez/ 官网地址 https://tez.apache.org/releases/apac…

云备份项目--客户端编写

文章目录 10. 客户端工具类10.1 整体的类10.2 测试 11 客户端数据管理类11.1 整体的类11.2 测试 12. 客户端业务处理12.1 整体的类 完整的代码–gitee链接 10. 客户端工具类 10.1 整体的类 在windows平台下进行开发&#xff0c;Util.hpp实际上是客户端FileUtil.hpp和JsonUtil…

MySQL 的事务与多版本并发控制(MVCC)的那些事

什么是事务原子性:一致性隔离性 问题1: 为什么MySQL要使用mvcc实现隔离性而不使用 锁 解决并发问题?持久性 问题2: MySQL 不是磁盘数据库吗,持久化为什么是 redo log 保证的?问题 3: redo log 储存了什么东西,持久化(崩溃恢复是怎么做的?)问题 4 : MySQL 的 bing log (二进制…

Eplan 项目结构(高层代号、安装地点、位置代号)

Eplan中的项目结构分为3个层次&#xff1a; &#xff08;1&#xff09;功能面结构。指明这个系统的功能&#xff0c;有什么用途。在EPlan中&#xff0c;指的就是"高层代号&#xff08;&#xff09;"。 一般指的是线体。 &#xff08;2&#xff09;位置面结构。指明该…

OWASP ZAP之API 请求基础知识

ZAP API 提供对 ZAP 大部分核心功能的访问,例如主动扫描器和蜘蛛。ZAP API 在守护进程模式和桌面模式下默认启用。如果您使用 ZAP 桌面,则可以通过访问以下屏幕来配置 API: Tools -> Options -> API。 ZAP 需要 API 密钥才能通过 REST API 执行特定操作。必须在所有 …

短信通知在 IOS 17/18 中不起作用?这是修复方法

问题 “我最近将 iPhone 更新到了 iOS 17/18。我真的很兴奋&#xff0c;直到我发现 iOS 17/18 中没有 iMessage 文本通知。此后我的兴奋变成了失望。请告诉我如何解决这个问题&#xff1f; ” 我们知道这可能是一个大问题&#xff0c;因为我们通常不会打开消息应用程序&#…

从0开始的opencv之旅(1)cv::Mat的使用

目录 Mat 存储方法 创建一个指定像素方式的图像。 尽管我们完全可以把cv::Mat当作一个黑盒&#xff0c;但是笔者的建议是仍然要深入理解和学习cv::Mat自身的构造逻辑和存储原理&#xff0c;这样在查找问题&#xff0c;或者是遇到一些奇奇怪怪的图像显示问题的时候能够快速的想…

机场安全项目|基于改进 YOLOv8 的机场飞鸟实时目标检测方法

目录 论文信息 背景 摘要 YOLOv8模型结构 模型改进 FFC3 模块 CSPPF 模块 数据集增强策略 实验结果 消融实验 对比实验 结论 论文信息 《科学技术与工程》2024年第24卷第32期刊载了中国民用航空飞行学院空中交通管理学院孔建国, 张向伟, 赵志伟, 梁海军的论文——…

《Rust权威指南》学习笔记(二)

枚举enum 1.枚举的定义和使用如下图所示&#xff1a; 定义时还可以给枚举的成员指定数据类型&#xff0c;例如&#xff1a;enum IpAddr{V4(u8, u8, u8, u8),V6(String),}。枚举的变体都位于标识符的命名空间下&#xff0c;使用::进行分隔。 2.一个特殊的枚举Option&#xff0…

OSI模型的网络层中产生拥塞的主要原因?

&#xff08; 1 &#xff09;缓冲区容量有限&#xff1b;&#xff08; 1.5 分&#xff09; &#xff08; 2 &#xff09;传输线路的带宽有限&#xff1b;&#xff08; 1.5 分&#xff09; &#xff08; 3 &#xff09;网络结点的处理能力有限&#xff1b;&#xff08; 1 分…

linux上安装MySQL教程

1.准备好MySQL压缩包&#xff0c;并进行解压 tar -xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar -C /usr/local 2.检查是否有mariadb数据库 rpm -aq|grep mariadb 关于mariadb:是MySQL的一个分支&#xff0c;主要由开源社区在维护&#xff0c;采用GPL授权许可 MariaDB的目…