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)
RuoYi-Vue-Plus (Logback 和 logback-plus.xml 、p6spy)
syfjava
RuoYi-Vue-Plus 学习 logback
项目后本地日志一、logback依赖打开最外层的pom.xml,查看SpringBoot的依赖配置。org.springframework.bootspring-boot-dependencies${spring-boot.version}pomimport
logback-spring.xml日志配置文件
A__cup__of__Java
logback spring xml
${log.pattern}maxFileSize,且日志文件大于maxFileSize,那么旧文件就会被删除,新的日志文件名就是按照fileNamePattern来创建。%i就表示索引,01、02、03,一直累加,如果看不到01、02,则表示之前的日志被删除了。-->${log.pattern}%d{yyyy-MM-dd}_%i.log-->/data/logs/service-name/%d{
2025网络安全学习路线 保姆级学习路线 非常详细 推荐学习
白帽黑客-晨哥
学习 web安全 安全 数据库 php
关键词:网络安全入门、渗透测试学习、零基础学安全、网络安全学习路线首先咱们聊聊,学习网络安全方向通常会有哪些问题1、打基础时间太长学基础花费很长时间,光语言都有几门,有些人会倒在学习linux系统及命令的路上,更多的人会倒在学习语言上;2、知识点掌握程度不清楚对于网络安全基础内容,很多人不清楚需要学到什么程度,囫囵吞枣,导致在基础上花费太多时间;看到很多小伙伴,买了HTML,PHP,数据库,计算机
springboot中配置logback-spring.xml
m0_74824755
面试 学习路线 阿里巴巴 spring spring boot logback
一、在src/main/resources目录下,也就是在classpath路径下创建logback-spring.xml注:springboot框架自动配置,如果更换名称,可在配置文件指定该文件即可-->%d{yyyy-MM-ddHH:mm:ss}[%thread]%-5level%logger{80}-%msg%n${log_dir}/info.logINFOACCEPTDENY${log_d
MySQL索引、视图与范式:高效数据库设计与优化秘籍
rain雨雨编程
Java编程 数据库 mysql 索引 视图 范式
♂️个人主页:@rain雨雨编程微信公众号:rain雨雨编程✍作者简介:持续分享机器学习,爬虫,数据分析希望大家多多支持,我们一起进步!如果文章对你有帮助的话,欢迎评论点赞收藏加关注+目录mysqlday04课堂笔记1、索引(index)1.1、什么是索引?1.2、索引的实现原理?1.3、添加索引的注意事项1.4、索引怎么创建?删除?语法是什么?1.5、如何查看某select中是否使用了索引1.
Java计算机毕业设计大学生体测数据管理系统源码+系统+数据库+lw文档
冰冰网络
java 开发语言 html
Java计算机毕业设计大学生体测数据管理系统源码+系统+数据库+lw文档Java计算机毕业设计大学生体测数据管理系统源码+系统+数据库+lw文档本源码技术栈:项目架构:B/S架构开发语言:Java语言开发软件:ideaeclipse前端技术:Layui、HTML、CSS、JS、JQuery等技术后端技术:JAVA运行环境:Win10、JDK1.8数据库:MySQL5.7/8.0源码地址:https
LINUX 安装mysql5.6.50 RPM
a21768541
数据库 mysql
今天要做一个MySql数据库的主从备份,由于现有的数据库,是使用宝塔安装的5.6.50版本,因此需要在新购买的服务器上安装MySql5.6.50版本,记录一下安装过程的碰见的各种问题1.下载安装包抖店云上的系统是CentOS7.964位,因此下载Redhat7系统下面的安装包下载地址:https://downloads.mysql.com/archives/community/只需要下载这两个安装
MD5解密为什么不能成功(解密算法)
浪九天
算法 Java java 算法
MD5解密为什么不能成功(解密算法)首先MD5的密文数量36的32次方;不加盐,不迭代,A-Z,a-z,0-9,8-16位密码,计算量:62的8次方至62的16次方工具类暴力算法结合数据库实现补充说明(原因)生成密文的工具类packagecom.decrypt;importorg.apache.shiro.crypto.hash.SimpleHash;publicclassDecyrpt{priv
在Spring Boot中如何使用Freemaker模板引擎
lozhyf
工作 学习 面试 spring boot 后端 java
在SpringBoot中使用FreeMarker模板引擎可以帮助你创建动态的Web页面。以下是详细的步骤和示例代码,介绍如何在SpringBoot项目里集成和使用FreeMarker。1.添加依赖如果你使用的是Maven项目,需要在pom.xml文件中添加FreeMarker相关依赖。SpringBoot提供了对应的Starter依赖,可简化配置过程。在标签内添加如下内容:xmlorg.sprin
Spring Boot定时任务原理
sjsjsbbsbsn
Spring八股 spring boot java 后端
SpringBoot定时任务原理在现代应用中,定时任务的调度是实现周期性操作的关键机制。SpringBoot提供了强大的定时任务支持,通过注解驱动的方式,开发者可以轻松地为方法添加定时任务功能。本文将深入探讨SpringBoot中定时任务的实现原理,重点分析@EnableScheduling和ScheduledAnnotationBeanPostProcessor的作用,以及任务如何被注册和执行。
SpringBoot(四十二)SpringBoot集成classfinal加密Jar包
camellias_
spring boot jar 后端
上文中,我们使用jasypt对项目中application.yml配置文件进行了加密。很多时候我们在将项目打成jar包之后,也是不希望被反编译的,毕竟是我们自己辛苦写的代码。那怎么办呢?有现成的轮子供我们使用:classfinal官网:ClassFinal:Java字节码加密工具这是一个开源项目,是的,这是一个开源项目,所以呢,classfinal混淆代码也不是一定不会被反编译的,这里要注意。Cl
Spring Boot与MyBatis
m0_74823658
面试 学习路线 阿里巴巴 spring boot mybatis 后端
SpringBoot与MyBatis的配置一、简介SpringBoot是一个用于创建独立的、基于Spring的生产级应用程序的框架,它简化了Spring应用的初始搭建以及开发过程。MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。将SpringBoot和MyBatis结合使用,可以高效地开发数据驱动的应用程序。二、环境准备(一)创建SpringBoot项目可以使用Sp
行业风向标|「博睿数据2024年度精选案例集——观测先锋」重磅发布
博睿数据Bonree
运维
云计算时代下,企业的应用交付链路越来越复杂,云原生、微服务、大型分布式等新技术给企业带来竞争力的同时,也带来了全新的挑战,传统IT监控已无法监测业务系统全链路的稳定性和可靠性,“云深不可见”难题突显。为应对这些复杂挑战,随时洞悉瞬息万变的环境中所发生的一切,“可观测性(Observability)”应运而生,它可以帮助企业实现数据价值最大化,加速企业数字化转型。作为中国IT运维监控及可观测性领域领
Java 集合:单列集合和双列集合的深度剖析
刘小炮吖i
Java后端开发面试题 Java 集合 java
引言在Java编程中,集合是一个非常重要的概念。它就像是一个容器,能够存储多个数据元素,帮助我们更方便地管理和操作数据。Java集合框架主要分为单列集合和双列集合两大类,它们各自有着独特的特点和适用场景。接下来,让我们深入探究这两种集合。单列集合单列集合就像是一列整齐排列的数据队伍,每个元素都是独立的个体,按照一定的规则存储和组织。在Java中,单列集合的根接口是java.util.Collect
DeepSeek掘金——SpringBoot 调用 DeepSeek API 快速实现应用开发
不二人生
大模型 DeepSeek掘金指南 spring boot deepseek
SpringBoot实现DeepSeekAPI调用1.项目依赖在pom.xml中添加以下依赖:org.springframework.bootspring-boot-starter-webfluxorg.projectlomboklombokcom.fasterxml.jackson.corejackson-databind2.项目结构<
面试基础--微服务架构:如何拆分微服务、数据一致性、服务调用
WeiLai1112
后端 架构 面试 微服务 java 分布式 中间件 后端
1.微服务的核心理念微服务架构是将大型单体应用拆分成一系列可独立部署、自治的服务,每个服务只专注于单一业务领域或子域。单一职责:每个微服务聚焦特定业务功能,如订单服务、用户服务、支付服务等。自治:服务拥有自己的数据与业务逻辑,服务之间尽量通过API或消息进行通信。独立部署:每个微服务都可独立上线、扩容或回滚,降低耦合风险。2.如何拆分微服务2.1业务域分析Domain-DrivenDesign(D
python单例模式数据库连接失败_Python 单例模式
Hsmiau
课程多面升级为Python3.7版本本课程持续更新中习惯的同学们可以关注一下。课程提供详细的课堂笔记,让你体验保姆式学习体验,并安排讲师做24小时内答疑,如果遇到问题请第一时间留言,我们会及时安排讲师答疑。课程目录:├──1-1Python的概述与环境安装│├──1-for老师课程开始简单介绍│├──2-python方向汇总│├──3-python历史介绍│├──4-python2和python3
C++STL容器之set
画个逗号给明天"
C++之STL容器 c++ 开发语言
1.介绍set容器是C++标准模板库(STL)中的一个关联容器,用于存储唯一的元素。set中的元素是自动排序的,不允许重复。set通常基于红黑树(一种自平衡二叉查找树)实现,因此插入、删除和查找操作的时间复杂度都为O(logn)。2.set用法(1)定义和初始化set的定义和初始化可以通过以下方式完成:std::setmySet;例如,定义一个int类型的set:std::setmySet;//定
Python 修改 pip 源
八级玄仙
tool python pip 开发语言
1.临时换源:#清华源pipinstallmarkdown-ihttps://pypi.tuna.tsinghua.edu.cn/simple#阿里源pipinstallmarkdown-ihttps://mirrors.aliyun.com/pypi/simple/#腾讯源pipinstallmarkdown-ihttp://mirrors.cloud.tencent.com/pypi/simp
庖丁解java(一篇文章学java)
庖丁解java
java 开发语言
(大家不用收藏这篇文章,因为这篇文章会经常更新,也就是删除后重发)一篇文章学java,这是我滴一个执念...当然,真一篇文章就写完java基础,java架构,java业务实现,java业务扩展,根本不可能.所以,这篇文章,就是一个索引,索什么呢?请看下文...关于决定开始写博文的介绍(一切故事的起点源于这一次反省)中小技术公司的软扩展(微服务扩展是否有必要?)-CSDN博客SpringCloud(
庖丁解java(一篇文章学java)
庖丁解java
java 开发语言
(大家不用收藏这篇文章,因为这篇文章会经常更新,也就是删除后重发)一篇文章学java,这是我滴一个执念...当然,真一篇文章就写完java基础,java架构,java业务实现,java业务扩展,根本不可能.所以,这篇文章,就是一个索引,索什么呢?请看下文...关于决定开始写博文的介绍(一切故事的起点源于这一次反省)中小技术公司的软扩展(微服务扩展是否有必要?)-CSDN博客SpringCloud(
中小技术公司的人才培养(微服务使用--降本心法)
庖丁解java
学习
为什么我写java技术博文的大逻辑和其他博主相反呢.这种思维其实是java本身给我带来的一种思维方式(当然也有可能就是我本身思维习惯也有这样的趋势,只是接触java之后负负得负,给我放大了)在java培训的过程中,java基础讲完之后,直接上手就是spring.这已经跨过了javaSE,utils,中间件.直接接触的就是框架.很快一个可运行的项目就可以通过IDEA创建出来.这就是java面向对象的
中小技术公司的软扩展(微服务扩展是否有必要?)
庖丁解java
微服务 架构 云原生
这篇文章主要探讨一个问题?前段时间爆火的微服务,容器,高并发等各类大厂扩散出来的'高级技术',如今又被不少人诟病,特别是一些中型公司,盲目技术迭代后,寒冬一来,发现企业代码逻辑太复杂,人员无法精简,甚至于最后连扩展都成了问题.最终导致成本无法控制,技术成为拖累,于是一部分程序员开始呼吁,还是单体技术架构好,中小企业,别去搞那些幺蛾子.关于这一个问题我想到两个解释角度:1,微服务的发展就是因为当时阿
Linux,容器,云环境(一个系统硬解析)
庖丁解java
linux 运维 服务器
一个系统,这篇文章要说的,就是后端代码写好之后,需要一个运行环境.而所谓环境,就是应用软件运行的基础,操作系统.那么中小公司,想要在软件部署上省最多的钱,选择就几乎可以没有争议的确认下来.Linux.而因为这系列架构用上了微服务拆分,如果是每个服务单独部署,那么互相联动起来的难度,技术复杂度又太过复杂,那将导致人力成本飙升.而这个问题,当然也已经被解决:容器技术与服务编排,docker,docke
微服务框架需要处理哪些问题?
起风哥
微服务 java 微服务 java 数据库
文章目录简述架构选择统一版本管理基础框架包管理业务框架包管理模型分层全局上下文管理数据结构定义上下文的传播前后端数据格式协定统一数据格式字段规范协定异常处理orm配置公共字段处理分页处理字段加解密缓存key的序列化哪些数据进行缓存消息队列key的规范队列的管理注册中心配置中心日志配置的热更新普通配置的热更新公共配置的抽取网关统一鉴权负载均衡限流降级日志的收集普通日志处理审计\操作日志处理文档管理定
SpringBoot + Vue 前后端跨域问题
游衍归者
SpringBoot与Vue spring boot vue.js java
1、报错信息java.lang.IllegalArgumentException:WhenallowCredentialsistrue,allowedOriginscannotcontainthespecialvalue"*"sincethatcannotbesetonthe"Access-Control-Allow-Origin"responseheader.Toallowcredentials
Spring MVC框架的依赖与配置实战
三冬评论员
本文还有配套的精品资源,点击获取简介:SpringMVC是一个基于Java的Web应用开发框架,作为Spring框架的一部分,它遵循MVC设计模式。在开发SpringMVC应用时,必须引入相关JAR包以支持其核心功能。这些JAR包括核心容器、数据访问、Web支持、AOP、工具类和测试模块。本篇文章将详细介绍SpringMVC所需的各依赖JAR包及其作用,并指导如何配置和使用这些依赖,以构建高效的W
c#编程:学习Linq,重几个简单示例开始
gu20
c# 学习 linq 开发语言
学习LINQ(LanguageIntegratedQuery)是掌握C#中数据处理和分析的重要一步。LINQ提供了一种简洁、声明性的方式来查询和操作内存中的数据集合(如数组、列表等)以及数据库中的数据。以下是一些入门级的经典LINQ示例,帮助理解LINQ的基本概念和使用方法。示例1:查询数组中的元素假设你有一个整数数组,你想要找到所有的偶数。csharpusingSystem;usingSyste
SpringBoot+Vue前后端跨域问题
笔上烽烟
SpringBoot Vue spring boot vue
随着分布式微服务的兴起,越来越多的公司在开发web项目的时候选择前后端分离的模式开发,前后端分开部署,使得分工更加明确,彻底解放了前端。我们知道,http请求都是无状态,现在比较流行的都是jwt的形式处理无状态的请求,在请求头上带上认证参数(token等),前后端分离有好处,也有坏处,第一次开发前后端分离项目的人,肯定会遇到前端请求跨域的问题,这个怎么处理呢?在说处理方案前,有必要说明一下为什么会
Spring 框架学习笔记:从零到精通的 21 个关键点
剑走偏锋o.O
开发语言 spring 学习 笔记 java
目录1.Spring概念介绍2.SpringIOC概念引入3.SpringIOC原理分析4.SpringXML方式实现DI5.SpringBean的生命周期6.SpringBean的自动装配7.Spring使用外部属性配置文件8.Spring注解方式管理Bean9.SpringJDK动态代理10.SpringCGLIB动态代理11.SpringAOP概念和原理12.SpringAOP注解方式实现1
辗转相处求最大公约数
沐刃青蛟
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: ken.wug@gmail.com
转载本文档请注明原文链接 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的第一个里程碑版本将在几天后发布,包含许多