1. 背景
一直在完善自己的微服务架构,其中包含分布式工作流服务的建设,目前采用的是Camunda工作流引擎。使用Camunda工作流,就会涉及到工作流引擎的用户体系如何与现有用户体系集成的问题(Flowable、Activity也类似)。现有设计中,工作流定位偏重于企业内部流程的流转,因此系统中设计了单位、部门、人员以及人事归属与Camunda工作流用户体系对应。
功能设计完成,就面临另外一个问题,如何解决现有人事体系数据如何【实时
】同步至Camunda工作流引擎中。如果现有体系数据与工作流数据在同一个库中,相对比较好解决。而微服务架构中,不同服务的数据通常存放在不同数据库中,那么就需要进行数据的同步。采用的方式不同,可以取得的效果也相同。
最初考虑如下两种方案,但是都略感不足:
ETL:使用ETL工具进行数据同步是典型的方式,可以选择工具也比较多。开源的ETL工具增量同步问题解决的并不理想,不使用增量同步数那么数据同步始终存在时间差;商业的ETL工具增量同步解决的比较好,但是庞大且昂贵。
消息队列:消息队列是多系统集成普遍采用的方式,可以很好的解决数据同步的实时问题。但是数据同步的两端都需要自己编写代码,一端写生产代码一端写消费代码,生产端代码还要捆绑现有体系数据所有操作,需要的编写量比较大。
查询对比的大量的资料,最终选择了Debezimu来解决以上问题以及未来更多数据同步的问题。
2. Debezium介绍
RedHat开源的Debezium是一个将多种数据源实时变更数据捕获,形成数据流输出的开源工具。 它是一种CDC(Change Data Capture)工具,工作原理类似大家所熟知的Canal, DataBus, Maxwell等,是通过抽取数据库日志来获取变更的。 官方介绍为:
Debezium is an open source distributed platform for change data capture. Start it up, point it at your databases, and your apps can start responding to all of the inserts, updates, and deletes that other apps commit to your databases. Debezium is durable and fast, so your apps can respond quickly and never miss an event, even when things go wrong
Debezium是一个分布式平台,它将您现有的数据库转换为事件流,因此应用程序可以看到数据库中的每一个行级更改并立即做出响应。Debezium构建在Apache Kafka之上,并提供Kafka连接兼容的连接器来监视特定的数据库管理系统。
Debezium现在已支持以下数据库:
MySQL
MongoDB
PostgreSQL
Oracle
SQL Server
Db2
Cassandra
Vitess
与ETL不同,Debezimu只支持在生产端连接数据库,消费端不支持连接数据库,而是需要自己编写代码接收Kafka消息数据。分析下来这种方式更加灵活,还可以很好利用现有微服务架构中的Kafka。
3. 快速搭建Debezimu测试环境。
目前,Debezium最新的Stable版本是1.6。 Debezium已经把要用到的Component打包成了Docker的Image,因此,我们只需要安装并启动Docker后就可以按下面的步骤快速搭建测试环境了。
如何在Windows下搭建Docker环境,可以参考个人的相关文章:
(1)Windows 10 2004 (20H1) 安装 Docker Desktop for Windows (2.3.0.2) 以 WSL 2 方式运行容器
(2)Windows 10 将 Docker Desktop for Windows(WSL 2 方式)文件存储移出C盘放置到其它目录
3.1 运行Zookeeper
docker run -it --name zookeeper -p 2181 :2181 -p 2888 :2888 -p 3888 :3888 debezium/zookeeper:1.6
3.2 运行Kafka
docker run -it --name kafka -p 9092 :9092 --link zookeeper:zookeeper debezium/kafka:1.6
3.3 运行PostgreSQL
docker run -it --rm --name postgres -p 5432 :5432 -e POSTGRES_USER = postgres -e POSTGRES_PASSWORD = postgres debezium/example-postgres:1.6
上面代码中使用的是:debezium/example-postgres:1.6,查看Debezimu官方文档以及其它示例都是这个。实际上Debezimu对PostgreSQL 9~13都进行了Docker封装,可以根据自己的需要在Docker Hub中选择响应的PostgreSQL版本。
debezium/postgres很小,使用也比较方便,而且也进行了必要的设置,无须再进行额外的配置就可以直接使用。
3.4 运行Debezimu Connect
docker run -it --rm --name connect -p 8083 :8083 -e GROUP_ID = 1 -e CONFIG_STORAGE_TOPIC = my_connect_configs -e OFFSET_STORAGE_TOPIC = my_connect_offsets -e STATUS_STORAGE_TOPIC = my_connect_statuses --link zookeeper:zookeeper --link kafka:kafka --link postgres:postgres debezium/connect:1.6
Debezium的container启动时需要传入如下环境变量:
GROUP_ID: 分组ID,若需要启动多个Debezium的实例组成集群,那么它们的GROUP_ID必须被设置为一样
CONFIG_STORAGE_TOPIC:下面需要调用Debezium提供的RestFUL API管理connector,connector的信息就是保存在CONFIG_STORAGE_TOPIC指定的kafka topic下。
OFFSET_STORAGE_TOPIC: connector监控数据流的offset,若我们使用的是PostgreSQL Connector,那么OFFSET_STORAGE_TOPIC指定的topic中存的就是PostgreSQL的lsn。
3.5 创建Connector
经过上面4个步骤后,Debezium的测试环境就搭建好了,现在需要调用Debezium提供的API创建connector,使Debezium与数据库之间建立关系。我们把下面的payload POST到http://:8083/connectors/
。
{
"name" : "fulfillment-connector" ,
"config" : {
"connector.class" : "io.debezium.connector.postgresql.PostgresConnector" ,
"database.hostname" : "192.168.99.100" ,
"database.port" : "5432" ,
"database.user" : "postgres" ,
"database.password" : "postgres" ,
"database.dbname" : "postgres" ,
"database.server.name" : "fulfillment" ,
"table.include.list" : "public.inventory"
}
}
“name”:注册到Kafka Connect服务的Connector名称
“connector.class”:PostgreSQL connector class名称
“database.hostname”:PostgreSQL 数据库地址
“database.port”:PostgreSQL 数据库端口
“database.user”:PostgreSQL 数据库用户名
“database.password”:PostgreSQL数据密码
“database.dbname”:连接的PostgreSQL数据库
“database.server.name”:虚拟的数据库Server名称,可以根据实际需求定义,消费Kafka数据时要使用该值
“table.include.list”:监听的数据表列表,以",“分割。PostgreSQL要将表名写全,格式”."。如果没有特定的Schema,那么就是默认的public
下面为完成的curl命令:
curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" localhost:8083/connectors/ -d '{"name": "fulfillment-connector", "config": {"connector.class": "io.debezium.connector.postgresql.PostgresConnector", "database.hostname": "192.168.99.100", "database.port": "5432", "database.user": "postgres", "database.password": "postgres", "database.dbname" : "postgres", "database.server.name": "fulfillment", "table.include.list": "public.inventory" }}'
上面是示例,因为使用的是Windows,个人觉得curl不方便,换用postman:
3.6 Docker Compose 配置
为了方便使用,将以上Docker命令整合为Docker Compose配置,具体如下:
version : "3"
services :
postgres :
image : debezium/postgres: 13
container_name : postgres
hostname : postgres
environment :
POSTGRES_USER : herodotus
POSTGRES_PASSWORD : herodotus
ports :
- 5432: 5432
zookeeper :
image : debezium/zookeeper: 1.6
container_name : zookeeper
restart : always
ports :
- 2181: 2181
- 2888: 2888
- 3888: 3888
kafka :
image : debezium/kafka: 1.6
container_name : kafka
restart : always
ports :
- 9092: 9092
environment :
ZOOKEEPER_CONNECT : zookeeper: 2181
BOOTSTRAP_SERVERS : kafka: 9092
depends_on :
- zookeeper
connect :
image : debezium/connect: 1.6
container_name : connect
restart : always
ports :
- 8083: 8083
environment :
GROUP_ID : 1
CONFIG_STORAGE_TOPIC : herodotus_connect_configs
OFFSET_STORAGE_TOPIC : herodotus_connect_offsets
STATUS_STORAGE_TOPIC : herodotus_connect_statuses
BOOTSTRAP_SERVERS : kafka: 9092
depends_on :
- kafka
4. 外部数据库配置
上一章节,介绍了Debezimu测试环境的方式,其中使用的debezium/postgres是已经进行过配置的,所以使用起来比较方便。在实际使用过程中,很多时候是使用独立搭建PostgreSQL,那么就需要对PostgreSQL进行配置。
4.1 以Docker的方式运行基础组件
本章节主要介绍Debezimu与独立的PostgreSQL数据库连接,因此除了PostgreSQL以外,Zookeeper、Kafka、Debezimu Connect仍旧使用Docker方式部署。具体部署的Docker Compose配置如下:
version : "3"
services :
zookeeper :
image : debezium/zookeeper: 1.6
container_name : zookeeper
hostname : zookeeper
environment :
ZOOKEEPER_SERVER_ID : 1
ports :
- 2181: 2181
- 2888: 2888
- 3888: 3888
kafka :
image : debezium/kafka: 1.6
container_name : kafka
hostname : kafka
ports :
- 9092: 9092
environment :
BROKER_ID : 1
ZOOKEEPER_CONNECT : zookeeper: 2181
KAFKA_LISTENERS : LISTENER_INNER: //kafka: 29092 , LISTENER_OUTER: //0.0.0.0: 9092
KAFKA_ADVERTISED_LISTENERS : LISTENER_INNER: //kafka: 29092 , LISTENER_OUTER: //192.168.101.10: 9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP : LISTENER_INNER: PLAINTEXT, LISTENER_OUTER: PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME : LISTENER_INNER
KAFKA_ALLOW_PLAINTEXT_LISTENER : 'yes'
KAFKA_AUTO_CREATE_TOPICS_ENABLE : 'true'
depends_on :
- zookeeper
connect :
image : debezium/connect: 1.6
container_name : connect
hostname : connect
ports :
- 8083: 8083
environment :
GROUP_ID : 1
CONFIG_STORAGE_TOPIC : herodotus_connect_configs
OFFSET_STORAGE_TOPIC : herodotus_connect_offsets
STATUS_STORAGE_TOPIC : herodotus_connect_statuses
BOOTSTRAP_SERVERS : kafka: 9092
depends_on :
- kafka
其中Kafka Listener相关的配置,是为了解决Spring Kafka连接Kafka会出现:Connection to node -1 could not be established. Broker may not be available.
问题。
4.2 修改PostgreSQL配置
Logical Decoding 功能是PostgreSQL在9.4加入的,它是一种机制,允许提取提交到事务日志的更改,并在输出插件的帮助下以用户友好的方式处理这些更改。输出插件使客户机能够使用更改。
PostgreSQL connector 读取和处理数据库变化主要包含两个部分:
Logical Decoding 输出插件:根据选择可能需要安装输出插件。运行PostgreSQL服务之前,必须配置replication slot
来启用你所选择的输出插件,有以下几个输出插件供选择:
decoderbufs
是基于Protobuf
的,目前由Debezimu社区维护
wal2json
是基于JSON
的,目前由wal2json社区维护
pgoutput
在PostgreSQL 10及以上版本中是标准的Logical Decoding 输出插件。是由PostgreSQL社区维护,由PostgreSQL自己用于Logical Replication。这个插件是内置安装的,所以不需要额外安装。
Java代码(就是连接Kafka Connect的代码):负责读取由Logical Decoding 输出插件产生的数据。
Logical Decoding 输出插件不支持DDL变更,这意味着Connector不能把DDL变更事件发送给消费者
Logical Decoding Replicaiton Slots支持数据库的primary
服务器。因此如果是PostgreSQL服务的集群,Connector只能在primary
服务器激活。如果primary
服务器出现问题,那么connector就会停掉。
4.2.1 修改PostgreSQL配置
在${PostgreSQL_HOME}/13/data目录下,找到postgresql.conf
。
修改以下配置:
wal_level=logical
max_wal_senders=1
max_replication_slots=1
wal_level
通知数据库使用 logical decoding 读取预写日志
max_wal_senders
通知数据库独立处理WAL变更的独立进程数量
max_replication_slots
通知数据库处理WAL变更流所允许最大replication slots数目
配置完成后记得重启数据库
4.2.2 设置数据库权限
需要给PostgreSQL 用户分配replication权限。定义一个PostgreSQL role,至少 分配REPLICATION
和LOGION
两项权限,示例代码如下:
CREATE ROLE < name> REPLICATION LOGIN;
具体操作可以参考一下脚本:
CREATE USER user WITH PASSWORD 'pwd' ;
ALTER ROLE user replication ;
grant CONNECT ON DATABASE test to user ;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO user ;
4.3 创建Connector
把下面的payload POST到http://:8083/connectors/
{
"name" : "herodotus-connector" ,
"config" : {
"connector.class" : "io.debezium.connector.postgresql.PostgresConnector" ,
"database.hostname" : "192.168.101.10" ,
"database.port" : "15432" ,
"database.user" : "athena" ,
"database.password" : "athena" ,
"database.dbname" : "athena" ,
"database.server.name" : "herodotus" ,
"slot.name" : "herodotus_slot" ,
"table.include.list" : "public.sys_organization" ,
"publication.name" : "herodotus_public_connector" ,
"publication.autocreate.mode" : "filtered" ,
"plugin.name" : "pgoutput"
}
}
postman 界面操作如下图: payload有两个字段,name是connector的名字,config是connector的配置信息,下表为config中的字段的解释:
字段名称
说明
connector.class
connector的实现类,本文使用的是io.debezium.connector.postgresql.PostgresConnector,因为我们的数据库是PostgreSQL
database.hostname
数据库服务的IP或域名
database.port
数据库服务的端口
database.user
连接数据库的用户
database.password
连接数据库的密码
database.dbname
数据库名
database.server.name
每个被监控的表在Kafka都会对应一个topic,topic的命名规范是..
slot.name
PostgreSQL的复制槽(Replication Slot)名称
table.include.list
如果设置了table.include.list,即在该list中的表才会被Debezium监控
plugin.name
PostgreSQL服务端安装的解码插件名称,可以是decoderbufs, wal2json, wal2json_rds, wal2json_streaming, wal2json_rds_streaming 和 pgoutput。如果不指定该值,则默认使用decoderbufs。 本例子中使用了pgoutput,因为它是PostgreSQL 10+自带的解码器,而其他解码器都必须在PostgreSQL服务器安装插件。
publication.name
PostgreSQL端的WAL发布(publication)名称,每个Connector都应该在PostgreSQL有自己对应的publication,如果不指定该参数,那么publication的名称为dbz_publication
publication.autocreate.mode
该值在plugin.name设置为pgoutput才会有效。有以下三个值:all_tables - debezium会检查publication是否存在,如果publication不存在,connector则使用脚本CREATE PUBLICATION FOR ALL TABLES创建publication,即该发布者会监控所有表的变更情况。disabled - connector不会检查有无publication存在,如果publication不存在,则在创建connector会报错.filtered - 与all_tables不同的是,debezium会根据connector的配置中的table.include.list生成生成创建publication的脚本: CREATE PUBLICATION FOR TABLE 。例如,本例子中,“table.include.list"值为"public.sys_organization”,则publication只会监控这个表的变更情况。
下面结合本例子中connector的配置信息对几个重点属性进行进一步说明:
Slot.name 重点说明
按照上例Debezium会在PostgreSQL创建一个名为herodotus_slot
的复制槽,本例中创建的connector需要通过该复制槽获取数据变更的信息。
可以通过以下sql查看复制槽的信息:
select * from pg_replication_slots;
上图中,active_pid为14200,即进程ID为14200的wal_sender进程已经在使用该复制槽与Debezium交互了
database.server.name和table.include.list
当connector获取到数据变更的信息后,会把该信息转化为统一的数据格式,并发布到Kafka的topic中。Debezium规定一个表对应一个topic,topic的名字的格式为 ..,本例中的表的数据变更消息将保存到Kafka的topic herodotus.public.sys_organization中。
可以通过以下代码查看接收到的信息
@KafkaListener ( topics = { "herodotus.public.sys_organization" } , groupId = "herodotus.debezium" )
public void received ( String message) {
log. info ( "[Herodotus] |- Recived message from Debezium : [{}]" , message) ;
}
5. 运行测试
现在,可以基于以上环境的配置,进行Debezium捕获数据效果的测试。可以进入到Kafka容器中,使用使用Kafka提供的kafka-console-consumer.sh
查看Topic接收到的数据。具体命令如下:
bin/kafka-console-consumer.sh --bootstrap-server 192.168 .101.10:9092 --topic herodotus.public.sys_organization
5.1 Insert 测试
在数据库sys_organization
中插入一条数据
Kafka的消费者命令行工具收到了来自Debezium发布的数据变更消息: 格式化后的消息体如下,其中schema字段在此先忽略,重点放payload.before,payload.after及payload.op字段上:
{
"schema" : {
...
} ,
"payload" : {
"before" : null ,
"after" : {
"organization_id" : "4" ,
"create_time" : null ,
"ranking" : null ,
"update_time" : null ,
"description" : null ,
"is_reserved" : null ,
"reversion" : null ,
"status" : 1 ,
"a4_biz_org_id" : null ,
"biz_org_code" : null ,
"biz_org_desc" : null ,
"biz_org_id" : null ,
"biz_org_name" : null ,
"biz_org_type" : null ,
"organization_name" : "AAAAA" ,
"parent_id" : null ,
"partition_code" : null ,
"short_name" : null
} ,
"source" : {
"version" : "1.6.0.Final" ,
"connector" : "postgresql" ,
"name" : "herodotus" ,
"ts_ms" : 1626594964405 ,
"snapshot" : "false" ,
"db" : "athena" ,
"sequence" : "[\"63461608\",\"63461608\"]" ,
"schema" : "public" ,
"table" : "sys_organization" ,
"txId" : 2460 ,
"lsn" : 63461896 ,
"xmin" : null
} ,
"op" : "c" ,
"ts_ms" : 1626594964846 ,
"transaction" : null
}
}
由于是insert操作,所以op为c (create),before为null,after为我们插入的数据。
5.2 Update 测试
在数据库sys_organization
中修改一条数据
Kafka的消费者命令行工具收到了来自Debezium发布的数据变更消息: 格式化后的消息体如下:
{
"schema" : {
...
} ,
"payload" : {
"before" : null ,
"after" : {
"organization_id" : "4" ,
"create_time" : null ,
"ranking" : null ,
"update_time" : null ,
"description" : null ,
"is_reserved" : null ,
"reversion" : null ,
"status" : 1 ,
"a4_biz_org_id" : null ,
"biz_org_code" : null ,
"biz_org_desc" : null ,
"biz_org_id" : null ,
"biz_org_name" : null ,
"biz_org_type" : null ,
"organization_name" : "BBBBB" ,
"parent_id" : null ,
"partition_code" : null ,
"short_name" : null
} ,
"source" : {
"version" : "1.6.0.Final" ,
"connector" : "postgresql" ,
"name" : "herodotus" ,
"ts_ms" : 1626595173601 ,
"snapshot" : "false" ,
"db" : "athena" ,
"sequence" : "[\"63466888\",\"63466888\"]" ,
"schema" : "public" ,
"table" : "sys_organization" ,
"txId" : 2461 ,
"lsn" : 63467176 ,
"xmin" : null
} ,
"op" : "u" ,
"ts_ms" : 1626595173825 ,
"transaction" : null
}
}
进行更新产品信息的操作后,consumer将收到一条op为u (update)的信息,after为修改后的数据。
5.3 Delete测试
在数据库sys_organization
中删除一条数据
Kafka的消费者命令行工具收到了来自Debezium发布的数据变更消息: 格式化后的消息体如下:
{
"schema" : {
...
} ,
"payload" : {
"before" : {
"organization_id" : "3" ,
"create_time" : null ,
"ranking" : null ,
"update_time" : null ,
"description" : null ,
"is_reserved" : null ,
"reversion" : null ,
"status" : null ,
"a4_biz_org_id" : null ,
"biz_org_code" : null ,
"biz_org_desc" : null ,
"biz_org_id" : null ,
"biz_org_name" : null ,
"biz_org_type" : null ,
"organization_name" : null ,
"parent_id" : null ,
"partition_code" : null ,
"short_name" : null
} ,
"after" : null ,
"source" : {
"version" : "1.6.0.Final" ,
"connector" : "postgresql" ,
"name" : "herodotus" ,
"ts_ms" : 1626594566933 ,
"snapshot" : "false" ,
"db" : "athena" ,
"sequence" : "[\"63461120\",\"63461120\"]" ,
"schema" : "public" ,
"table" : "sys_organization" ,
"txId" : 2458 ,
"lsn" : 63461176 ,
"xmin" : null
} ,
"op" : "d" ,
"ts_ms" : 1626594567136 ,
"transaction" : null
}
}
进行删除产品信息的操作后,consumer将收到一条op为d (delete)的信息,before为刪除前的数据,after为null。
6.总结
通过Debezimu进行数据同步,不仅解决了传统ETL时效性不高的问题,还解决了基于消息队列需要两端编写代码的工程量,而且基于容器的方式更适合微服务架构的使用,使用Kafka进行消费端的整合,使得整合方式更加灵活便捷、终端类型更加丰富。
示例代码地址:
参考资料
[1] :https://blog.csdn.net/foshansuperinter/article/details/110856979
[2] :https://access.redhat.com/documentation/en-us/red_hat_integration/2020.q1/html/debezium_user_guide/debezium-connector-for-postgresql
[3] :https://debezium.io/documentation/reference/1.6/connectors/postgresql.html#postgresql-overview
你可能感兴趣的:(Spring,Cloud,微服务,容器,微服务架构,数据库,etl)
guava loadingCache代码示例
IM 胡鹏飞
Java 工具类介绍
publicclassTest2{publicstaticvoidmain(String[]args)throwsException{LoadingCachecache=CacheBuilder.newBuilder()//设置并发级别为8,并发级别是指可以同时写缓存的线程数.concurrencyLevel(8)//设置缓存容器的初始容量为10.initialCapacity(10)//设置缓存
Android 开源组件和第三方库汇总
gyyzzr
Android Android 开源框架
转载1、github排名https://github.com/trending,github搜索:https://github.com/search2、https://github.com/wasabeef/awesome-android-ui目录UIUI卫星菜单节选器下拉刷新模糊效果HUD与Toast进度条UI其它动画网络相关响应式编程地图数据库图像浏览及处理视频音频处理测试及调试动态更新热更新
Java大厂面试实录:谢飞机的电商场景技术问答(Spring Cloud、MyBatis、Redis、Kafka、AI等)
Java大厂面试实录:谢飞机的电商场景技术问答(SpringCloud、MyBatis、Redis、Kafka、AI等)本文模拟知名互联网大厂Java后端岗位面试流程,以电商业务为主线,由严肃面试官与“水货”程序员谢飞机展开有趣的对话,涵盖SpringCloud、MyBatis、Redis、Kafka、SpringSecurity、AI等热门技术栈,并附详细解析,助力求职者备战大厂面试。故事设定谢
Java大厂面试故事:谢飞机的互联网音视频场景技术面试全纪录(Spring Boot、MyBatis、Kafka、Redis、AI等)
来旺
Java场景面试宝典 Java Spring Boot MyBatis Kafka Redis 微服务 AI
Java大厂面试故事:谢飞机的互联网音视频场景技术面试全纪录(SpringBoot、MyBatis、Kafka、Redis、AI等)互联网大厂技术面试不仅考察技术深度,更注重业务场景与系统设计能力。本篇以严肃面试官与“水货”程序员谢飞机的对话,带你体验音视频业务场景下的Java面试全过程,涵盖主流技术栈,并附详细答案解析,助你面试无忧。故事场景设定谢飞机是一名有趣但技术基础略显薄弱的程序员,这次应
CentOS7环境卸载MySQL5.7
Hadoop_Liang
mysql 数据库 mysql
备份重要数据切记,卸载之前先备份mysql重要的数据。备份一个数据库例如:备份名为mydatabase的数据库到backup.sql的文件中mysqldump-uroot-ppassword123mydatabase>backup.sql备份所有数据库mysqldump-uroot-ppassword123--all-databases>all_databases_backup.sql注意:-p后
php SPOF
贵哥的编程之路(热爱分享 为后来者)
PHP语言经典程序100题 php 开发语言
1.什么是单点故障(SPOF)?单点故障指的是系统中某个组件一旦失效,整个系统或服务就会不可用。常见的单点有:数据库、缓存、Web服务器、负载均衡、网络设备等。2.常见单点故障场景只有一台数据库服务器,宕机后所有业务不可用只有一台Redis缓存,挂掉后缓存全部失效只有一台Web服务器,挂掉后网站无法访问只有一个负载均衡节点,挂掉后流量无法分发只有一条网络链路,断开后所有服务失联3.消除单点故障的主
centos7安装 mysql5.7(安装包)
heiPony
linux mysql mariadb centos mysql
一.卸载centos7自带数据库查看系统自带的Mariadbrpm-qa|grepmariadbmariadb-libs-5.5.44-2.el7.centos.x86_64卸载rpm-e--nodepsmariadb-libs-5.5.44-2.el7.centos.x86_64删除etc目录下的my.cnfrm/etc/my.cnf二.检查mysql是否存在(有就卸载,删除相关文件)rpm-q
EMQX 社区版单机和集群部署
pcj_888
MQTT MQTT EMQ
EMQ支持Docker,宿主机,k8s部署;支持单机或集群部署。以下给出EMQX社区版单机和集群部署方法1.Docker单机部署官方推荐最小配置:2核4G下载容器镜像dockerpullemqx/emqx:5.3.2启动容器dockerrun-d--nameemqx\-p1883:1883\-p8083:8083\-p8883:8883\-p8084:8084\-p18083:18083\emqx
MySQL Explain 详解:从入门到精通,让你的 SQL 飞起来
引言:为什么Explain是SQL优化的“照妖镜”?在Java开发中,我们常常会遇到数据库性能瓶颈的问题。一条看似简单的SQL语句,在数据量增长到一定规模后,可能会从毫秒级响应变成秒级甚至分钟级响应,直接拖慢整个应用的性能。此时,你是否曾困惑于:为什么这条SQL突然变慢了?索引明明建了,为什么没生效?到底是哪里出了问题?答案就藏在MySQL的EXPLAIN命令里。EXPLAIN就像一面“照妖镜”,
OpenWebUI(12)源码学习-后端constants.py常量定义文件
青苔猿猿
AI大模型 openwebui constants常量定义
目录文件名:`constants.py`功能概述:主要功能点详解1.**MESSAGES枚举类**2.**WEBHOOK_MESSAGES枚举类**3.**ERROR_MESSAGES枚举类**✅默认错误模板✅认证与用户相关错误✅资源冲突与重复错误✅验证失败类错误✅权限限制类错误✅文件上传与格式错误✅模型与API错误✅请求频率与安全限制✅数据库与配置错误4.**TASKS枚举类**✅总结实际应用场
玩转Docker | 使用Docker部署gopeed下载工具
心随_风动
玩转Docker docker 容器 运维
玩转Docker|使用Docker部署gopeed下载工具前言一、gopeed介绍Gopeed简介主要特点二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署gopeed服务下载镜像创建容器检查容器状态检查服务端口安全设置四、访问gopeed应用五、测试与下载六、总结前言在当今信息爆炸的时代,高效地获取和管理网络资源变得尤为重要。无论是下载大型文件还是进行日常的数据传输,一个稳
Spring Cloud Gateway 的执行链路详解
愤怒的代码
SpringCloud spring cloud
SpringCloudGateway的执行链路详解核心目标明确SpringCloudGateway的请求处理全过程(从接收到请求→到转发→到返回响应),方便你在合适的生命周期节点插入你的逻辑。核心执行链路图(执行顺序)┌──────────────┐│客户端请求│└────┬─────────┘↓┌────┴─────────────┐│NettyHttpServer│←→ReactorNetty
RocketMQ 核心特性实战详解
愤怒的代码
RocketMQ实战 rocketmq
RocketMQ核心特性实战详解本文基于RocketMQ4.x+rocketmq-spring-boot-starter2.3.1,从零搭建,逐步讲解RocketMQ11大核心特性,每一段代码都能直接跑。0.项目环境准备依赖引入在pom.xml文件添加:org.apache.rocketmqrocketmq-spring-boot-starter2.3.1配置文件application.ymlse
Docker指定网桥和指定网桥IP
$dockernetworklsNETWORKIDNAMEDRIVER7fca4eb8c647bridgebridge9f904ee27bf5nonenullcf03ee007fb4hosthostBridge默认bridge网络,我们可以使用dockernetworkinspect命令查看返回的网络信息,我们使用dockerrun命令是将网络自动应用到新的容器Host如果是hosts模式,启动容
Java 调用 HTTP 接口的 7 种方式:全网最全指南
Java调用HTTP接口的7种方式:全网最全指南在开发过程中,调用HTTP接口是最常见的需求之一。本文将详细介绍Java中7种主流的调用HTTP接口的方式,包括每种工具的优缺点和完整代码实现。1.使用RestTemplateRestTemplate是Spring提供的同步HTTP客户端,适用于传统项目。尽管从Spring5开始被标记为过时,它仍然是许多开发者的首选。示例代码importorg.sp
docker0网卡没有ip一步解决
ξ流ぁ星ぷ132
tcp/ip 网络 服务器
正常查看ip的时候一直显示没有ip这里先删除docker0网卡iplinkdeletedocker0然后重启服务systemctlrestartdocker再次查看显示有ip了并且查看配置文件也是正常的cat/etc/docker/daemon.json{"registry-mirrors":["https://docker.m.daocloud.io","https://docker.imgdb
自动化运维工程师面试题解析【真题】
ZabbixAgent默认监听的端口是A.10050。以下是关键分析:选项排除:C.80是HTTP默认端口,与ZabbixAgent无关。D.5432是PostgreSQL数据库的默认端口,不涉及ZabbixAgent。B.10051是ZabbixServer的默认监听端口,用于接收Agent发送的数据,而非Agent自身的监听端口。ZabbixAgent的配置:根据官方文档,ZabbixAgen
什么是OA系统?使用OA系统对企业有哪些好处?
OA系统(OfficeAutomationSystem),即办公自动化系统,是将现代化办公和计算机网络功能结合起来的一种新型的办公方式。是现代企业管理中一种重要的信息化工具,它通过计算机技术、网络技术和数据库技术等手段,实现企业内部办公流程的自动化和信息化管理。使企业的信息交流更加顺畅,办公流程更加高效,从而提高企业的运营效率和管理水平。一、主要功能1.文档管理文档存储与检索:OA系统可以集中存储
LangChain中的向量数据库接口-Weaviate
洪城叮当
langchain 数据库 经验分享 笔记 交互 人工智能 知识图谱
文章目录前言一、原型定义二、代码解析1、add_texts方法1.1、应用样例2、from_texts方法2.1、应用样例3、similarity_search方法3.1、应用样例三、项目应用1、安装依赖2、引入依赖3、创建对象4、添加数据5、查询数据总结前言 Weaviate是一个开源的向量数据库,支持存储来自各类机器学习模型的数据对象和向量嵌入,并能无缝扩展至数十亿数据对象。它提供存储文档嵌
Flutter——数据库Drift开发详细教程(七)
怀君
flutter flutter 数据库
目录入门设置漂移文件入门变量数组定义表支持的列类型漂移特有的功能导入嵌套结果LIST子查询Dart互操作SQL中的Dart组件类型转换器现有的行类Dart文档注释结果类名称支持的语句自定义SQL类型定义类型使用自定义类型在Dart中在SQL中方言意识支持的SQLite扩展json1fts5地缘垄断自定义查询带有生成的api的语句自定义选择语句自定义更新语句入门Drift提供了一个dart_api来
Docker容器底层原理详解:从零理解容器化技术
Debug Your Career
面试 docker 容器 docker java
一、容器本质:一个“隔离的进程”关键认知:Docker容器并不是一个完整的操作系统,而是一个被严格隔离的进程。这个进程拥有独立的文件系统、网络、进程视图等资源,但它直接运行在宿主机内核上(而虚拟机需要模拟硬件和操作系统)。类比理解:想象你在一个办公楼里租了一间独立办公室(容器)。你有自己的桌椅(文件系统)、电话分机(网络)、门牌号(主机名),但共享整栋楼的水电(宿主机内核)和电梯(硬件资源)。办公
android中百度定位、城市选择列表,右侧字母展示
好久好久没光顾过自己空空的博客了,做项目的时候都是逛着别人的博客急着把功能实现,近来闲下来了总结总结。这个城市选择功能也是当时做项目急着实现从哪找来的框架不记得了,然后改改用到项目中来的。非常感谢提供最初源码的博主,主要的区别是添加了搜索功能、定位功能,把以前的操作本地数据库sqlite的部分,改为操作对assest文件的操作,封装的有百度地图定位方法、可删除的edittext。百度地图的key需
JVM与Spring Boot核心解析
AIHacksCash
Java场景面试宝典 Java JVM Spring Boot
我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、Spri
Flutter——数据库Drift开发详细教程之迁移(九)
怀君
flutter flutter 数据库
迁移入门引导式迁移配置用法例子切换到make-migrations开发过程中手动迁移迁移后回调导出模式导出架构下一步是什么?调试导出架构的问题修复这个问题架构迁移助手自定义分步迁移转向逐步迁移手动生成测试迁移编写测试验证数据完整性在运行时验证数据库模式迁移器API一般提示迁移视图、触发器和索引复杂的迁移更改列的类型更改列约束删除列重命名列合并列添加新列入门Drift通过严格的架构确保查询类型安全。
C++STL-set
s15335
C++STL c++ 开发语言
一.基础概念set也是一种容器,像vector,string这样,但它是树形容器。在物理结构上是二叉搜索树,逻辑上还是线性结构。set容器内元素不可重复,multiset内容器元素可以重复;这两个容器,插入的元素都是有序排列。二.基础用法1.set对象创建1.默认构造函数sets1;2.初始化列表sets2_1={9,8,7,6,5};//56789sets2_2({9,8,7,7,6,5});/
Spring WebFlux 响应式编程原理与实战指南
SpringWebFlux响应式编程原理与实战指南一、技术背景与应用场景随着微服务与高并发的迅速发展,传统的阻塞式编程模型在处理大量并发请求时容易导致线程资源耗尽、响应延迟增高。SpringWebFlux基于ReactiveStreams规范,通过非阻塞、背压机制,实现高吞吐、低延迟的Web服务。典型应用场景包括:实时数据推送:WebSocket或Server-SentEvents场景。高并发AP
Kubernetes自动扩缩容方案对比与实践指南
浅沫云归
后端技术栈小结 kubernetes autoscaling devops
Kubernetes自动扩缩容方案对比与实践指南随着微服务架构和容器化的广泛采用,Kubernetes自动扩缩容(Autoscaling)成为保障生产环境性能稳定与资源高效利用的关键技术。面对水平Pod扩缩容、垂直资源调整、集群节点扩缩容以及事件驱动扩缩容等多种需求,社区提供了HPA、VPA、ClusterAutoscaler、KEDA等多种方案。本篇文章将从业务背景、方案对比、优缺点分析、选型建
老系统改造增加初始化,自动化数据源配置(tomcat+jsp+springmvc)
老系统改造增加初始化,自动化数据源配置一、前言二、改造描述1、环境说明2、实现步骤简要思考三、开始改造1、准备sql初始化文件2、启动时自动读取jdbc文件,创建数据源,如未配置,需要一个默认的临时数据源2.1去掉spingmvc原本配置的固定dataSource,改为动态dataSource2.2代码类,这里是示例,我就不管规范了,放到一起2.2.1DynamicDataSourceConfig
zookeeper etcd区别
sun007700
zookeeper etcd 分布式
ZooKeeper与etcd的核心区别体现在设计理念、数据模型、一致性协议及适用场景等方面。ZooKeeper基于ZAB协议实现分布式协调,采用树形数据结构和临时节点特性,适合传统分布式系统;而etcd基于Raft协议,以高性能键值对存储为核心,专为云原生场景优化,是Kubernetes等容器编排系统的默认存储组件。12架构与设计目标差异ZooKeeper。设计定位:专注于分
面试官:Spring 如何控制 Bean 的加载顺序?
在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能。核心原则:依赖驱动加载SpringIoC容器会构建一个依赖关系图(DependencyGraph)。如果BeanA依赖于BeanB(例如,A的构造函数需要一个B类型的参数),Spring会保证在创建BeanA之前,BeanB已经被完全创建和初始化好了。@ServicepublicclassServiceA{
辗转相处求最大公约数
沐刃青蛟
C++ 漏洞
无言面对”江东父老“了,接触编程一年了,今天发现还不会辗转相除法求最大公约数。惭愧惭愧!
为此,总结一下以方便日后忘了好查找。
1.输入要比较的两个数a,b
忽略:2.比较大小(因为后面要的是大的数对小的数做%操作)
3.辗转相除(用循环不停的取余,如a%b,直至b=0)
4.最后的a为两数的最大公约数
&
F5负载均衡会话保持技术及原理技术白皮书
bijian1013
F5 负载均衡
一.什么是会话保持? 在大多数电子商务的应用系统或者需要进行用户身份认证的在线系统中,一个客户与服务器经常经过好几次的交互过程才能完成一笔交易或者是一个请求的完成。由于这几次交互过程是密切相关的,服务器在进行这些交互过程的某一个交互步骤时,往往需要了解上一次交互过程的处理结果,或者上几步的交互过程结果,服务器进行下
Object.equals方法:重载还是覆盖
Cwind
java generics override overload
本文译自StackOverflow上对此问题的讨论。
原问题链接
在阅读Joshua Bloch的《Effective Java(第二版)》第8条“覆盖equals时请遵守通用约定”时对如下论述有疑问:
“不要将equals声明中的Object对象替换为其他的类型。程序员编写出下面这样的equals方法并不鲜见,这会使程序员花上数个小时都搞不清它为什么不能正常工作:”
pu
初始线程
15700786134
暑假学习的第一课是讲线程,任务是是界面上的一条线运动起来。
既然是在界面上,那必定得先有一个界面,所以第一步就是,自己的类继承JAVA中的JFrame,在新建的类中写一个界面,代码如下:
public class ShapeFr
Linux的tcpdump
被触发
tcpdump
用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支 持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。
实用命令实例
默认启动
tcpdump
普通情况下,直
安卓程序listview优化后还是卡顿
肆无忌惮_
ListView
最近用eclipse开发一个安卓app,listview使用baseadapter,里面有一个ImageView和两个TextView。使用了Holder内部类进行优化了还是很卡顿。后来发现是图片资源的问题。把一张分辨率高的图片放在了drawable-mdpi文件夹下,当我在每个item中显示,他都要进行缩放,导致很卡顿。解决办法是把这个高分辨率图片放到drawable-xxhdpi下。
&nb
扩展easyUI tab控件,添加加载遮罩效果
知了ing
jquery
(function () {
$.extend($.fn.tabs.methods, {
//显示遮罩
loading: function (jq, msg) {
return jq.each(function () {
var panel = $(this).tabs(&
gradle上传jar到nexus
矮蛋蛋
gradle
原文地址:
https://docs.gradle.org/current/userguide/maven_plugin.html
configurations {
deployerJars
}
dependencies {
deployerJars "org.apache.maven.wagon
千万条数据外网导入数据库的解决方案。
alleni123
sql mysql
从某网上爬了数千万的数据,存在文本中。
然后要导入mysql数据库。
悲剧的是数据库和我存数据的服务器不在一个内网里面。。
ping了一下, 19ms的延迟。
于是下面的代码是没用的。
ps = con.prepareStatement(sql);
ps.setString(1, info.getYear())............;
ps.exec
JAVA IO InputStreamReader和OutputStreamReader
百合不是茶
JAVA.io操作 字符流
这是第三篇关于java.io的文章了,从开始对io的不了解-->熟悉--->模糊,是这几天来对文件操作中最大的感受,本来自己认为的熟悉了的,刚刚在回想起前面学的好像又不是很清晰了,模糊对我现在或许是最好的鼓励 我会更加的去学 加油!:
JAVA的API提供了另外一种数据保存途径,使用字符流来保存的,字符流只能保存字符形式的流
字节流和字符的难点:a,怎么将读到的数据
MO、MT解读
bijian1013
GSM
MO= Mobile originate,上行,即用户上发给SP的信息。MT= Mobile Terminate,下行,即SP端下发给用户的信息;
上行:mo提交短信到短信中心下行:mt短信中心向特定的用户转发短信,你的短信是这样的,你所提交的短信,投递的地址是短信中心。短信中心收到你的短信后,存储转发,转发的时候就会根据你填写的接收方号码寻找路由,下发。在彩信领域是一样的道理。下行业务:由SP
五个JavaScript基础问题
bijian1013
JavaScript call apply this Hoisting
下面是五个关于前端相关的基础问题,但却很能体现JavaScript的基本功底。
问题1:Scope作用范围
考虑下面的代码:
(function() {
var a = b = 5;
})();
console.log(b);
什么会被打印在控制台上?
回答:
上面的代码会打印 5。
&nbs
【Thrift二】Thrift Hello World
bit1129
Hello world
本篇,不考虑细节问题和为什么,先照葫芦画瓢写一个Thrift版本的Hello World,了解Thrift RPC服务开发的基本流程
1. 在Intellij中创建一个Maven模块,加入对Thrift的依赖,同时还要加上slf4j依赖,如果不加slf4j依赖,在后面启动Thrift Server时会报错
<dependency>
【Avro一】Avro入门
bit1129
入门
本文的目的主要是总结下基于Avro Schema代码生成,然后进行序列化和反序列化开发的基本流程。需要指出的是,Avro并不要求一定得根据Schema文件生成代码,这对于动态类型语言很有用。
1. 添加Maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<proj
安装nginx+ngx_lua支持WAF防护功能
ronin47
需要的软件:LuaJIT-2.0.0.tar.gz nginx-1.4.4.tar.gz &nb
java-5.查找最小的K个元素-使用最大堆
bylijinnan
java
import java.util.Arrays;
import java.util.Random;
public class MinKElement {
/**
* 5.最小的K个元素
* I would like to use MaxHeap.
* using QuickSort is also OK
*/
public static void
TCP的TIME-WAIT
bylijinnan
socket
原文连接:
http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.html
以下为对原文的阅读笔记
说明:
主动关闭的一方称为local end,被动关闭的一方称为remote end
本地IP、本地端口、远端IP、远端端口这一“四元组”称为quadruplet,也称为socket
1、TIME_WA
jquery ajax 序列化表单
coder_xpf
Jquery ajax 序列化
checkbox 如果不设定值,默认选中值为on;设定值之后,选中则为设定的值
<input type="checkbox" name="favor" id="favor" checked="checked"/>
$("#favor&quo
Apache集群乱码和最高并发控制
cuisuqiang
apache tomcat 并发 集群 乱码
都知道如果使用Http访问,那么在Connector中增加URIEncoding即可,其实使用AJP时也一样,增加useBodyEncodingForURI和URIEncoding即可。
最大连接数也是一样的,增加maxThreads属性即可,如下,配置如下:
<Connector maxThreads="300" port="8019" prot
websocket
dalan_123
websocket
一、低延迟的客户端-服务器 和 服务器-客户端的连接
很多时候所谓的http的请求、响应的模式,都是客户端加载一个网页,直到用户在进行下一次点击的时候,什么都不会发生。并且所有的http的通信都是客户端控制的,这时候就需要用户的互动或定期轮训的,以便从服务器端加载新的数据。
通常采用的技术比如推送和comet(使用http长连接、无需安装浏览器安装插件的两种方式:基于ajax的长
菜鸟分析网络执法官
dcj3sjt126com
网络
最近在论坛上看到很多贴子在讨论网络执法官的问题。菜鸟我正好知道这回事情.人道"人之患好为人师" 手里忍不住,就写点东西吧. 我也很忙.又没有MM,又没有MONEY....晕倒有点跑题.
OK,闲话少说,切如正题. 要了解网络执法官的原理. 就要先了解局域网的通信的原理.
前面我们看到了.在以太网上传输的都是具有以太网头的数据包. 
Android相对布局属性全集
dcj3sjt126com
android
RelativeLayout布局android:layout_marginTop="25dip" //顶部距离android:gravity="left" //空间布局位置android:layout_marginLeft="15dip //距离左边距
// 相对于给定ID控件android:layout_above 将该控件的底部置于给定ID的
Tomcat内存设置详解
eksliang
jvm tomcat tomcat内存设置
Java内存溢出详解
一、常见的Java内存溢出有以下三种:
1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存。
可以利用JVM提
Java6 JVM参数选项
greatwqs
java HotSpot jvm jvm参数 JVM Options
Java 6 JVM参数选项大全(中文版)
作者:Ken Wu
Email:
[email protected]
转载本文档请注明原文链接 http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm!
本文是基于最新的SUN官方文档Java SE 6 Hotspot VM Opt
weblogic创建JMC
i5land
weblogic jms
进入 weblogic控制太
1.创建持久化存储
--Services--Persistant Stores--new--Create FileStores--name随便起--target默认--Directory写入在本机建立的文件夹的路径--ok
2.创建JMS服务器
--Services--Messaging--JMS Servers--new--name随便起--Pers
基于 DHT 网络的磁力链接和BT种子的搜索引擎架构
justjavac
DHT
上周开发了一个磁力链接和 BT 种子的搜索引擎 {Magnet & Torrent},本文简单介绍一下主要的系统功能和用到的技术。
系统包括几个独立的部分:
使用 Python 的 Scrapy 框架开发的网络爬虫,用来爬取磁力链接和种子;
使用 PHP CI 框架开发的简易网站;
搜索引擎目前直接使用的 MySQL,将来可以考虑使
sql添加、删除表中的列
macroli
sql
添加没有默认值:alter table Test add BazaarType char(1)
有默认值的添加列:alter table Test add BazaarType char(1) default(0)
删除没有默认值的列:alter table Test drop COLUMN BazaarType
删除有默认值的列:先删除约束(默认值)alter table Test DRO
PHP中二维数组的排序方法
abc123456789cba
排序 二维数组 PHP
<?php/*** @package BugFree* @version $Id: FunctionsMain.inc.php,v 1.32 2005/09/24 11:38:37 wwccss Exp $*** Sort an two-dimension array by some level
hive优化之------控制hive任务中的map数和reduce数
superlxw1234
hive hive优化
一、 控制hive任务中的map数: 1. 通常情况下,作业会通过input的目录产生一个或者多个map任务。 主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改);2. 
Spring Boot 1.2.4 发布
wiselyman
spring boot
Spring Boot 1.2.4已于6.4日发布,repo.spring.io and Maven Central可以下载(推荐使用maven或者gradle构建下载)。
这是一个维护版本,包含了一些修复small number of fixes,建议所有的用户升级。
Spring Boot 1.3的第一个里程碑版本将在几天后发布,包含许多