低耦合双写一致性方案-使用canal+MQ

需求:继上一篇使用xxljob实现数据的全量同步到es后,当数据库中新增、删除、修改数据时,应该对es中的对应索引库实现增量同步。
本文介绍了2种双写一致性方案,对其中使用MQ的方案进行了实现。

1. 方案设计

1.1 数据一致性问题分析

在这里插入图片描述

案例问题分析:

1:管理员调用秒杀服务添加秒杀活动,并给秒杀活动添加商品。

2:秒杀服务调用IgeMonitor服务生成静态页。

3:秒杀服务调用goods服务将商品数量和价格存入Redis缓存。

4:秒杀服务调用goods服务调用Search服务将商品数据写入ES索引库。

上面是秒杀案例需要同步操作调用的服务流程,如果采用同步调用,性能效率比较低,且服务之间耦合度极高。我们需要寻找一种方法,降低seckill服务和其他服务的耦合度,并且实现静态页、缓存数据、索引数据一致性。

1.2 双写一致性设计-TCP模式

在秒杀活动添加中,有这几个流程:

  • 静态页生成
  • 价格、数量加入缓存
  • 数据入索引库

如果我们要求这几个操作强一致性,可以采取如下方案:

在这里插入图片描述

我们以上面案例为例,可以采用Canal作为中间数据同步管道:

1:开启需要实现数据一致性操作的数据库Binlog,当执行增删改的时候,会记录日志。
2:管理员操作seckill服务添加秒杀活动和活动商品,并将数据修改到数据库,操作结束。
3:Canal订阅数据库增量数据,并编写一个Java服务获取增量数据。
4:在Java服务中实现对IgeMonitor调用以及Goods服务调用和Search服务调用,从而实现数据一致性。

这种模式适合某些特定场景,对数据一致性要求比较高的时候,可以采取这种模式。这种模式虽然能解决强一致性问题,但Canal和其他服务之间耦合度较高。

1.3 双写一致性-MQ模式

如果我们要求这几个操作(静态页生成,价格、数量加入缓存,数据入索引库)强一致性要求不高,可以采取如下方案:
在这里插入图片描述

上图是双写一致性设计,几乎能满足微服务架构下所有服务数据一致性,实现流程如下:

1:开启需要实现数据一致性操作的数据库Binlog,当执行增删改的时候,会记录日志。

2:使用Canal监听数据库变更的Binlog日志,同时将变更数据推送至Kakfa。

3:各个服务为实现数据双写一致性,可以按需订阅Kafka中的数据,实现数据同步到文件服务、ElasticSearch、Redis等。

方案特性:

  • 基于MySQL Binlog增量订阅,业务0侵入性。
  • 增量数据采用Kafka实现收集,Kafka吞吐量极高,能满足高并发场景下数据一致性需求。
  • 数据同步,跨语言、跨系统,灵活度极高,只要能订阅Kafka数据,必能同步。
  • 订阅Kafka数据,能解决的数据一致性业务场景丰富:
    • 可以实现多消费者实现多服务、多库同步。
    • 也可以基于单组消费者消费,实现单服务、单库同步。

无论是哪种模式,都需要用到Canal和MySQL Binlog,所以我们需要掌握着2个知识点。

平时在工作中,2种数据一致性模式往往有不同应用场景,可以根据业务需搭配使用。

2. springboot集成kafka

3. canal

本章小结:

  • MySQL Binlog介绍
  • 主从复制机制
  • Canal工作原理介绍
  • Canal安装

3.1 MySQL Binlog日志

MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDLDML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。使用Binlog日志一定会有性能损耗,在官方文档记录中,开启二进制日志大概会有1%的性能损耗。

二进制有两个最重要的使用场景:

#1:主从复制
MySQL Replication在Master端开启binlog,Mster把它的二进制日志传递给slaves来达到master-slave数据一致的目的。

#2:数据恢复
由于binlog日志记录了DDL和DML语句,所以可以实现数据恢复,通过使用mysqlbinlog工具来使恢复数据。

MysqlBinlog三种模式:

1)statement模式:每一条会修改数据的sql都会记录到master的binlog中,slave在复制的时候sql进程会解析成和原来master端执行相同的sql再执行。
2)ROW模式:日志中会记录成每一行数据被修改后的快照,而后在slave端再对相同的数据进行修改,只记录要修改的数据,只有value,不会有sql多表关联的状况。
3)MIXED:混合模式复制,结合Statement和ROW的优势,会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。

  • 如何查看是否开启binlog?
#查看是否开启了binlog
mysql> show variables like 'log_%';
+----------------------------------------+--------+
| Variable_name                          | Value  |
+----------------------------------------+--------+
| log_bin                                | OFF    |
| log_bin_basename                       |        |
| log_bin_index                          |        |
| log_bin_trust_function_creators        | OFF    |
| log_bin_use_v1_row_events              | OFF    |
| log_builtin_as_identified_by_password  | OFF    |
+----------------------------------------+--------+
通过上面的语句可以查看是否开启了binlog,很显然bin_log的值为OFF表示关闭。

如何开启binlog?

#开启binlog,这里是基于docker容器下安装canal实现
#1:将容器配置文件mysqld.cnf拷贝到宿主机中
docker cp mysql:/etc/mysql/mysql.conf.d/mysqld.cnf ./
#2:修改mysqld.cnf配置文件
vi mysqld.cnf

#3:添加如下配置,开启binlog,添加到[mysqld]下面
#log-bin=mysql-bin 开启binlog,而mysql-bin是日志文件的前缀
#server_id服务唯一标识
#binlog-format指日志记录格式
server_id=1
binlog-format=ROW
log-bin=mysql-bin

#4:将修改后的文件拷贝到容器中
docker cp ./mysqld.cnf mysql:/etc/mysql/mysql.conf.d/

#5:重启容器
docker restart mysql

#6:查看是否开启了binlog
mysql> show variables like 'log_%';
+----------------------------------------+--------------------------------+
| Variable_name                          | Value                          |
+----------------------------------------+--------------------------------+
| log_bin                                | ON                             |
| log_bin_basename                       | /var/lib/mysql/mysql-bin       |
| log_bin_index                          | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators        | OFF                            |
| log_bin_use_v1_row_events              | OFF                            |
+----------------------------------------+--------------------------------+

3.2 开启binlog详细步骤

查看是否开启了binlog

[root@192 ~]# docker exec -it mysql /bin/bash
root@4cfb9a43ab13:/# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'log_%';
+----------------------------------------+--------+
| Variable_name                          | Value  |
+----------------------------------------+--------+
| log_bin                                | OFF    |
| log_bin_basename                       |        |
| log_bin_index                          |        |
| log_bin_trust_function_creators        | OFF    |
| log_bin_use_v1_row_events              | OFF    |
| log_builtin_as_identified_by_password  | OFF    |
| log_error                              | stderr |
| log_error_verbosity                    | 3      |
| log_output                             | FILE   |
| log_queries_not_using_indexes          | OFF    |
| log_slave_updates                      | OFF    |
| log_slow_admin_statements              | OFF    |
| log_slow_slave_statements              | OFF    |
| log_statements_unsafe_for_binlog       | ON     |
| log_syslog                             | OFF    |
| log_syslog_facility                    | daemon |
| log_syslog_include_pid                 | ON     |
| log_syslog_tag                         |        |
| log_throttle_queries_not_using_indexes | 0      |
| log_timestamps                         | UTC    |
| log_warnings                           | 2      |
+----------------------------------------+--------+
21 rows in set (0.01 sec)

mysql> 

开启binlog系列命令

[root@192 ~]# docker cp mysql:/etc/mysql/mysql.conf.d/mysqld.cnf ./
                                               Successfully copied 3.58kB to /root/./
[root@192 ~]# ls
anaconda-ks.cfg  images  minio  mysqld.cnf
[root@192 ~]# vi mysqld.cnf 

修改mysqld.cnf
在这里插入图片描述

[root@192 ~]# docker cp ./mysqld.cnf mysql:/etc/mysql/mysql.conf.d/
                                             Successfully copied 3.58kB to mysql:/etc/mysql/mysql.conf.d/
[root@192 ~]# docker restart mysql
mysql
[root@192 ~]# docker exec -it mysql bash
root@4cfb9a43ab13:/# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.36-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'log_%';
+----------------------------------------+--------------------------------+
| Variable_name                          | Value                          |
+----------------------------------------+--------------------------------+
| log_bin                                | ON                             |
| log_bin_basename                       | /var/lib/mysql/mysql-bin       |
| log_bin_index                          | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators        | OFF                            |
| log_bin_use_v1_row_events              | OFF                            |
| log_builtin_as_identified_by_password  | OFF                            |
| log_error                              | stderr                         |
| log_error_verbosity                    | 3                              |
| log_output                             | FILE                           |
| log_queries_not_using_indexes          | OFF                            |
| log_slave_updates                      | OFF                            |
| log_slow_admin_statements              | OFF                            |
| log_slow_slave_statements              | OFF                            |
| log_statements_unsafe_for_binlog       | ON                             |
| log_syslog                             | OFF                            |
| log_syslog_facility                    | daemon                         |
| log_syslog_include_pid                 | ON                             |
| log_syslog_tag                         |                                |
| log_throttle_queries_not_using_indexes | 0                              |
| log_timestamps                         | UTC                            |
| log_warnings                           | 2                              |
+----------------------------------------+--------------------------------+
21 rows in set (0.01 sec)

mysql> exit
Bye
root@4cfb9a43ab13:/# exit
exit
[root@192 ~]# 

3.3 canal工作原理

  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
  • MySQL master 收到 dump 请求,开始推送 binary logslave (即 canal )
  • canal 解析 binary log 对象(原始为 byte 流)

3.4 canal安装

基于Docker命令安装Canal:

docker pull canal/canal-server:v1.1.5
docker run -p 11111:11111 --name=canal --restart=always -d canal/canal-server:v1.1.5
# Kafka的支持是从1.1.0开始,所以我们使用MQ模式的时候,最佳版本选择1.1.5,支持RabbitMQ、RocketMQ、Kafka。

因为canal伪装自己为slave,因此mysql需要对这个slave库进行授权
数据库授权账号

create user canal@'%' IDENTIFIED by 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;

详细步骤

[root@192 ~]# docker exec -it mysql bash
root@4cfb9a43ab13:/# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.36-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create user canal@'%' IDENTIFIED by 'canal';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> 

3.3 canal配置

考虑到下面3个问题:

  • 集成kafka,canal应该把数据库的数据修改信息推送到哪?–>配置kafka
  • 指定监听表:canal监听的应该是我们想让他监听的表,而不是数据库的所有表的修改数据
  • 推送规则:canal把信息推送到MQ的哪个topic?

1)Kafka服务信息配置

进入Canal容器,首先要配置Kafka服务信息,主要修改/home/admin/canal-server/conf/canal.properties文件,配置如下:

#进入Canal容器
docker exec -it canal /bin/bash

#进入配置目录
cd /home/admin/canal-server/conf

#编辑配置文件canal.properties
vi canal.properties

#设置Canal数据流模式为kafka,可选值有tcp, kafka, rocketMQ, rabbitMQ,默认是tcp
canal.serverMode = kafka

#设置Kafka服务地址
kafka.bootstrap.servers = 192.168.211.130:9092,192.168.211.130:9093,192.168.211.130:9094

详细步骤

[root@192 ~]# docker exec -it canal /bin/bash
[root@ca8714734388 admin]# cd /home/admin/canal-server/conf
[root@ca8714734388 conf]# ls
canal_local.properties  canal.properties  example  logback.xml  metrics  spring
[root@ca8714734388 conf]# vi canal.properties 

在这里插入图片描述在这里插入图片描述

2)监听数据库配置

接下来要配置监听的数据源信息,修改/home/admin/canal-server/conf/example/instance.properties文件,配置如下:

#修改/home/admin/canal-server/conf/example/instance.properties文件
vi /home/admin/canal-server/conf/example/instance.properties

#position info 配置监听数据源,将数据源地址换成指定的数据源
canal.instance.master.address=192.168.211.130:3306

# username/password  授权账号配置,这个账号其实就是我们在开启MySQL Binlog创建的授权账号
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal

#table regex 配置监听的数据库表
#所有表:.* or .*\\..*
#canal schema下所有表: canal\\..*
#canal下的以canal打头的表:canal\\.canal.*
#canal schema下的一张表:canal.test1
#多个规则组合使用:canal\\..*,mysql.test1,mysql.test2 (逗号分隔)
#监听demo数据库下的所有表,配置如下:
canal.instance.filter.regex=demo\\..*

3)topic配置

当数据库数据发生变更的时候,我们希望将数据推送至Kafka中,所以需要配置队列,配置队列可以直接将队列名字硬编码写死,但不推荐这种做法,推荐用数据库名_表名的方式。仍然要配置instance.properties

修改如下配置即可:

# mq config
# 固定MQ的名字
#canal.mq.topic=example
#根据表的名字动态创建MQ,例如demo下的tb_user表变化,创建队列demo_tb_user
canal.mq.dynamicTopic=.*\\..*

详细步骤

在这里插入图片描述
修改instance.properties
在这里插入图片描述
在这里插入图片描述重启canal

docker restart canal

3.4 测试

修改数据库数据
在这里插入图片描述

查看kafka的topic发现多了个leadnews_wemedia_wm_news

[root@192 ~]# docker restart canal
canal
[root@192 ~]# docker exec -it kafka /bin/bash
bash-5.1# kafka-topics.sh --zookeeper 192.168.200.131:2181 --list
__consumer_offsets
leadnews_wemedia_wm_news
test
user-topic
bash-5.1# 

ps:kafka相关命令

kafka-topics.sh --zookeeper 192.168.200.131:2181 --list  //查看所有topic
kafka-topics.sh --delete --topic topic_name --zookeeper 192.168.200.131:2181 //删除名为topic_name的topic
kafka-topics.sh --delete --topic leadnews_wemedia_wm_news --zookeeper 192.168.200.131:2181

4. springboot监听topic

kafka配置

spring:
  application:
    name: leadnews-kafka
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.200.131:8848
      config:
        server-addr: 192.168.200.131:8848
        file-extension: yml
  kafka:
    bootstrap-servers: 192.168.200.131:9092
    producer: # producer 生产者
      retries: 0 # 重试次数
      acks: 0 # 应答级别:多少个分区副本备份完成时向生产者发送ack确认(可选0、1、all/-1)
      batch-size: 16384 # 批量大小
      buffer-memory: 33554432 # 生产端缓冲区大小
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
    consumer: # consumer消费者
      group-id: xxxgroup # 默认的消费组ID
      enable-auto-commit: true # 是否自动提交offset
      auto-commit-interval: 100  # 提交offset延时(接收到消息后多久提交offset)
      # earliest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
      # latest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
      # none:topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
      auto-offset-reset: latest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

Listener

@Component
public class BinlogListener {

    @KafkaListener(topics = "leadnews_wemedia_wm_news",groupId = "pay")
    public void WmNewsListenerPay(ConsumerRecord<String,String> record){
        System.out.println("pay模块");
        String msg = record.value();
        System.out.println(msg);
    }

    @KafkaListener(topics = "leadnews_wemedia_wm_news",groupId = "shop")
    public void WmNewsListenerShop(ConsumerRecord<String,String> record){
        System.out.println("shop模块");
        String msg = record.value();
        System.out.println(msg);
    }
}

修改数据
在这里插入图片描述
消费者接收到binlog的修改信息
在这里插入图片描述

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

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

相关文章

vue 点击复制文本到剪贴板

一、首先在vue文件的template中定义复制按钮 <div size"small" v-if"item.prop jadeCode" class"cell-container"><span>{{ scope.row.jadeCode }}</span> <button click"handleCopy(scope.row.jadeCode)" clas…

js——数据操作——实现阶梯价格排序——基础积累

最近在写网络报价的时候&#xff0c;遇到一个需求&#xff0c;就是要根据采购数量&#xff0c;找到符合数量的阶梯区间&#xff0c;并找到最便宜的采购价格。 比如下面&#xff1a; let originViewList [{id:1,incrementalQuantity:10,priceList:[{minQuantity:1,price:20},…

el-upload上传图片,视频可获取视频时长。

对element-ui组件的upload组件再一次封装&#xff0c;简单记录。下面是效果图。 注意点&#xff1a;该组件现在仅支持单图和单个视频上传。 <template><div :style"myStyle"><divclass"uploads":style"{width: upWith px,height: up…

零门槛微调大模型:基于 Ludwig 低代码框架使用 LoRA 技术微调实践

一、Ludwig 介绍 自然语言处理 (NLP) 和人工智能 (AI) 的飞速发展催生了许多强大的模型&#xff0c;它们能够理解和生成如同人类般的文本&#xff0c;为聊天机器人、文档摘要等应用领域带来了革命性的改变。然而&#xff0c;释放这些模型的全部潜力需要针对特定用例进行微调。…

我用通义千问做了个银从初级法规考试答题AI助手

我用通义千问做了个银从初级法规考试答题AI助手 起因方法&#xff1a;创建方法&#xff1a;微调成果展示 起因 多选考试实在太难了&#xff0c;惨不忍睹的正确率&#xff0c;博主我就想有一个专门刷多选的工具&#xff0c;但找了半天没找到。然后就想到用通义试试&#xff0c;…

MySQL 服务无法启动

常见原因: 检查端口占用&#xff1a; 使用命令行工具&#xff08;如netstat&#xff09;来检查3306端口是否已被其他程序占用,输入netstat -ano&#xff08;Windows&#xff09;或netstat -tulnp | grep 3306&#xff08;Linux/Mac&#xff09;来查找3306端口的占用情况。如果…

excel转pdf并且加水印,利用ByteArrayOutputStream内存流不产生中间文件

首先先引入包&#xff1a;加水印和excel转PDF的 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.12</version></dependency><dependency><groupId>org.apache.poi&l…

【Numpy】深入解析numpy.diag()函数

numpy.diag()&#xff1a;深入探索NumPy库中的对角矩阵操作 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f3…

统计绘图:基于matplotlib包绘制双轴图

本文介绍通过 Python的matplotlib包 绘制 双轴图&#xff08;Dual Y-Axis Plot&#xff09;&#xff0c;即双 y 轴图&#xff0c;又称双纵坐标图。 这类图表的主要用途是显示两个具有不同数值范围的变量在同一 x 轴上的 变化趋势&#xff0c;从而便于比较和分析。&#xff08;…

docker中安装jenkins,并在node和cloud上跑通基于源码控制SCM的pipeline

目录 一、摘要 二、部署和使用 1. docker部署jenkins 1.1 准备数据目录 1.2 拉取jenkins镜像并启动 1.3 初始化配置 1.3.1 登录容器查看初始化密码 1.3.2 访问jenkins并输入初始化密码 1.3.3 创建管理员账户 1.3.4 初始化完成 2. jenkins使用之多分支流水线 2.1 准…

大模型落地竞逐,云计算大厂“百舸争流”

作者 | 辰纹 来源 | 洞见新研社 从ChatGPT到Sora&#xff0c;从图文到视频&#xff0c;从通用大模型到垂直大模型……经过了1年多时间的探索&#xff0c;大模型进入到以落地为先的第二阶段。 行业的躁动与资本的狂热相交汇&#xff0c;既造就了信仰派的脚踏实地&#xff0c;也…

适用于当下的红色系统可视化大屏,大量图。

特定场合下使用红色系可视化大屏是可以的&#xff0c;但是千万要注意时间和场合&#xff0c;平时最好别用。

获取支持Windows7的最新Edge离线版本

从110版本开始&#xff0c;微软Edge和谷歌停止了对Win7、Win8/8.1的支持&#xff0c;后续又发布了几版安全更新&#xff0c;截止目前为止&#xff0c;能支持Win7的版本是 109.0.1518.140。 如果你想用最新版本谷歌浏览器&#xff0c;可以考虑下Supermium&#xff0c;这个浏览器…

内存马实战(持续更新中)

注&#xff1a;这篇文章记录在我的语雀里面&#xff0c;语雀格式好看一点&#xff0c;地址&#xff1a; https://ganmaocai.yuque.com/ghgp8x/zoy1yn/faet35ae9gpxzn61 计划 复现以下框架的内存马注入&#xff1a; shiro&#xff1a; 普通内存马 冰蝎马 WebSocket马 xxl-job…

C++ 计时器

文章目录 一、简介二、实现代码2.1 windows平台2.2 C标准库 三、实现效果 一、简介 有时候总是会用到一些计时的操作&#xff0c;这里也整理了一些代码&#xff0c;包括C标准库以及window自带的时间计算函数。 二、实现代码 2.1 windows平台 StopWatch.h #ifndef STOP_WATCH_H…

JWT的详解

一.什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在网络应用间安全地传递信息。它是一种紧凑的、自包含的方式&#xff0c;用于在用户和服务之间以 JSON 对象的形式安全地传输信息。 JWT 主要由三部分…

计算机系统基础 7 分支程序的实现

简单条件转移指令 根据单个标志位的值&#xff08;CF&#xff0c; SF&#xff0c;OF&#xff0c;PF&#xff0c;ZF&#xff09;来确定是否转移&#xff0c; 如果条件成立&#xff0c;则&#xff08;EIP&#xff09; 位移量 ➡ EIP&#xff0c;否则什么也不做。 注意&#xff0…

c# 将数据库连接字符串写到配置文件中,及获取

考虑到代码的安全性&#xff0c;已经修改起来的方便性&#xff0c;我们常常不会将数据库连接字符串直接放在代码中&#xff0c;而是将这个字符串放到一个App.config配置文件中&#xff0c;赋值给一个变量&#xff0c;然后再在代码中引用这个变量。 具体做法如下: ①展开项目名称…

微星笔记本618爆款推荐清单,好评有礼活动火热进行中

微星笔记本618爆款推荐清单&#xff0c;好评有礼活动火热进行中 又是一年一度的618大促&#xff0c;作为电子数码产品的主场&#xff0c;准备选购笔记本的消费者早已翘首以盼有更实惠的价格~ 不负期待&#xff0c;微星笔记本携多款性价比爆款笔记本、Claw掌上游戏机&#xff0…

Google Find My Device:科技守护,安心无忧

在数字化的时代&#xff0c;我们的生活与各种智能设备紧密相连。而 Google Find My Device 便是一款为我们提供安心保障的实用工具。 一、Find My Decice Netword的定义 谷歌的Find My Device Netword旨在通过利用Android设备的众包网络的力量&#xff0c;帮助用户安全的定位所…