1、版本说明

软件&镜像
版本&镜像信息
说明
Kubernetes
v1.23.7
k8s服务器
Kuboard
v3.5.2.0
k8s连接管理工具
Canal
v1.1.6
数据同步
Canal-deployer
canal/canal-server:latest
canal-deplyer镜像版本信息
Canal-adapter
funnyzak/canal-adapter:1.1.6
canal-adapter镜像版本信息

注意:

1> canal deployer由于官方发布的1.1.6版本不兼容jdk1.8(具体原因可参看相关issue,https://github.com/alibaba/canal/issues/4358),后续官方发布了latest版本兼容jdk1.8,所以这里deployer的镜像版本采用latest版本(官方canal deployer镜像地址:https://hub.docker.com/r/canal/canal-server/tags);当然,官方1.1.6版本是兼容jdk11及以上版本的,如果不想采用latest版本,也可以重新采用jdk11及以上版本自己构建docker镜像即可(这里提供一个非官方的基于jdk11的canal deployer 1.1.6版本镜像,仅供参考:funnyzak/canal-server:1.1.6

2> 关于canal-adapter镜像说明,由于官方并未提供canal-adapter镜像,这部分查看issue也没有具体说明,鉴于canal 1.1.6版本存在不兼容jdk1.8版本的问题,所以当前docker hub上发布的基于jdk1.8版本的canal-adapter 1.1.6版本镜像,使用时均会发生部署失败的问题,因此这里使用了基于jdk11部署的canal-adapter镜像,关于此镜像说明可参看如下说明:https://github.com/funnyzak/canal-docker

3> 关于Kuboard说明,仅是一个k8s连接管理工具,如果介意,当然也可以采用原生方式部署,这里不做要求

2、MySQL数据库说明

MySQL数据库连接
MySQL数据库版本
说明
192.168.91.131:3306
5.7.34
源库连接地址
192.168.91.135:3306
5.7.34
目标库链接地址

3、k8s部署yml文件说明

1> 当前yml文件为两个MySQL数据库之间的同步,如果是MySQL和ES或者其他数据库之间的数据同步,此文档仅供参考;如果仅同步某个库下的某几张表数据,可以参考官方文档(https://github.com/alibaba/canal/wiki/Sync-RDB),修改对应配置,这里不再多做说明

2> 此yml文件部署方式为tcp方式,如使用kafka等MQ方式,请注意修改对应配置,此文档不再进行说明

3> 当前方式部署为增量数据同步,如需全量同步,可参考官方文档:https://github.com/alibaba/canal/wiki/ClientAdapter#324-%E6%89%8B%E5%8A%A8etl

4> 当前部署数据同步方式采用镜像同步,即源库和目标库之间的schema一致,从而实现两个MySQL数据库下的整个数据库中所有的数据表同步;若是单库单表数据同步,相关配置可参考官方文档(https://github.com/alibaba/canal/wiki/Sync-RDB),这里不再赘述

5> Canal相关配置通过configMap方式挂载,关于挂载到对应服务器文件的方式,感兴趣的小伙伴可以自行配置,这里不再赘述

6> 使用Kuboard工具可以直接复制如下部署文件,通过yml方式创建;当然通过其他k8s连接工具创建也是可以的,例如:kubesphere等

7> yml文件部署时,可以参考如下部署顺序,以减少部署失败的次数

(1)请先部署canal deployer、canal adapter对应的configMap文件

(2)之后再部署Zookeeper服务

(3)然后部署canal deployer服务,确保deployer服务部署启动成功

(4)最后再部署canal adapter服务

8> 部署过程中如果遇到部署问题,可查看issue寻找解决方案,官方issue地址:https://github.com/alibaba/canal/issues

3.1、Canal deployer部署文件

---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: canal-deployer
name: canal-deployer
namespace: canal-mysql
spec:
replicas: 1
minReadySeconds: 10
selector:
matchLabels:
app: canal-deployer
template:
metadata:
name: canal-deployer
labels:
app: canal-deployer
spec:
volumes:
- name: conf
configMap:
defaultMode: 493
name: canal-deployer-configmap
containers:
- name: canal-deployer
image: canal/canal-server:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /home/admin/canal-server/conf/canal.properties
name: conf
subPath: canal.properties
- mountPath: /home/admin/canal-server/conf/example/instance.properties
name: conf
subPath: instance.properties
- mountPath: /home/admin/app.sh
name: conf
subPath: app.sh
ports:
- containerPort: 11111
protocol: TCP
- containerPort: 11112
protocol: TCP ---
kind: Service
apiVersion: v1
metadata:
name: canal-deployer
namespace: canal-mysql
labels:
app: canal-deployer
spec:
ports:
- port: 11111
name: deployer
- port: 11112
name: metrics
clusterIP: None
selector:
app: canal-deployer ---
apiVersion: v1
kind: ConfigMap
metadata:
name: canal-deployer-configmap
namespace: canal-mysql
data:
app.sh: |-
#!/bin/bash
set -e source /etc/profile
export JAVA_HOME=/usr/java/latest
export PATH=$JAVA_HOME/bin:$PATH
touch /tmp/start.log
host=`hostname -i` # waitterm
# wait TERM/INT signal.
# see: http://veithen.github.io/2014/11/16/sigterm-propagation.html
waitterm() {
local PID
# any process to block
tail -f /dev/null &
PID="$!"
# setup trap, could do nothing, or just kill the blocker
trap "kill -TERM ${PID}" TERM INT
# wait for signal, ignore wait exit code
wait "${PID}" || true
# clear trap
trap - TERM INT
# wait blocker, ignore blocker exit code
wait "${PID}" 2>/dev/null || true
} # waittermpid "${PIDFILE}".
# monitor process by pidfile && wait TERM/INT signal.
# if the process disappeared, return 1, means exit with ERROR.
# if TERM or INT signal received, return 0, means OK to exit.
waittermpid() {
local PIDFILE PID do_run error
PIDFILE="${1?}"
do_run=true
error=0
trap "do_run=false" TERM INT
while "${do_run}" ; do
PID="$(cat "${PIDFILE}")"
if ! ps -p "${PID}" >/dev/null 2>&1 ; then
do_run=false
error=1
else
sleep 1
fi
done
trap - TERM INT
return "${error}"
} function checkStart() {
local name=$1
local cmd=$2
local timeout=$3
cost=5
while [ $timeout -gt 0 ]; do
ST=`eval $cmd`
if [ "$ST" == "0" ]; then
sleep 1
let timeout=timeout-1
let cost=cost+1
elif [ "$ST" == "" ]; then
sleep 1
let timeout=timeout-1
let cost=cost+1
else
break
fi
done
echo "start $name successful"
} function start_canal() {
echo "start canal ..."
managerAddress=`perl -le 'print $ENV{"canal.admin.manager"}'`
if [ ! -z "$managerAddress" ] ; then
# canal_local.properties mode
adminPort=`perl -le 'print $ENV{"canal.admin.port"}'`
if [ -z "$adminPort" ] ; then
adminPort=11110
fi su root -c 'cd /home/admin/canal-server/bin/ && sh restart.sh local 1>>/tmp/start.log 2>&1'
sleep 5
#check start
checkStart "canal" "nc 127.0.0.1 $adminPort -w 1 -z | wc -l" 30
else
metricsPort=`perl -le 'print $ENV{"canal.metrics.pull.port"}'`
if [ -z "$metricsPort" ] ; then
metricsPort=11112
fi destination=`perl -le 'print $ENV{"canal.destinations"}'`
if [[ "$destination" =~ ',' ]]; then
echo "multi destination:$destination is not support"
exit 1;
else
if [ "$destination" != "" ] && [ "$destination" != "example" ] ; then
if [ -d /home/admin/canal-server/conf/example ]; then
mv /home/admin/canal-server/conf/example /home/admin/canal-server/conf/$destination
fi
fi
fi su root -c 'cd /home/admin/canal-server/bin/ && sh restart.sh 1>>/tmp/start.log 2>&1'
sleep 5
#check start
checkStart "canal" "nc 127.0.0.1 $metricsPort -w 1 -z | wc -l" 30
fi
} function stop_canal() {
echo "stop canal"
su root -c 'cd /home/admin/canal-server/bin/ && sh stop.sh 1>>/tmp/start.log 2>&1'
echo "stop canal successful ..."
} function start_exporter() {
su root -c 'cd /home/admin/node_exporter && ./node_exporter 1>>/tmp/start.log 2>&1 &'
} function stop_exporter() {
su root -c 'killall node_exporter'
} echo "==> START ..." start_exporter
start_canal echo "==> START SUCCESSFUL ..." tail -f /dev/null &
# wait TERM signal
waitterm echo "==> STOP" stop_canal
stop_exporter echo "==> STOP SUCCESSFUL ..."
canal.properties: >-
canal.ip =
canal.register.ip =
canal.port = 11111
canal.metrics.pull.port = 11112
# 修改点: 此处值修改为部署的zookeeper服务的地址
canal.zkServers = zookeeper:2181
canal.withoutNetty = false
canal.serverMode = tcp
canal.destinations = example
canal.auto.scan = true canal.instance.detecting.enable = false
canal.instance.detecting.sql = select 1
canal.instance.detecting.interval.time = 3
canal.instance.detecting.retry.threshold = 3
canal.instance.detecting.heartbeatHaEnable = false canal.instance.transaction.size = 1024
canal.instance.fallbackIntervalInSeconds = 60 canal.instance.network.receiveBufferSize = 16384
canal.instance.network.sendBufferSize = 16384
canal.instance.network.soTimeout = 30 canal.instance.filter.druid.ddl = true
canal.instance.filter.query.dcl = false
canal.instance.filter.query.dml = false
canal.instance.filter.query.ddl = false
canal.instance.filter.table.error = false
canal.instance.filter.rows = false
canal.instance.filter.transaction.entry = false
canal.instance.filter.dml.insert = false
canal.instance.filter.dml.update = false
canal.instance.filter.dml.delete = false canal.conf.dir = ../conf
canal.instance.binlog.format = ROW,STATEMENT,MIXED
canal.instance.binlog.image = FULL,MINIMAL,NOBLOB
canal.instance.get.ddl.isolation = false
canal.instance.parser.parallel = true
canal.instance.parser.parallelThreadSize = 16 canal.instance.tsdb.enable = false
canal.instance.tsdb.dir = ${canal.conf.dir}/tsdb
canal.instance.tsdb.url = jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
canal.instance.tsdb.dbUsername = canal
canal.instance.tsdb.dbPassword = canal
canal.instance.tsdb.snapshot.interval = 24
canal.instance.tsdb.snapshot.expire = 360
canal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml canal.instance.global.mode = spring
canal.instance.global.lazy = false
canal.instance.global.spring.xml = classpath:spring/default-instance.xml
instance.properties: |-
canal.instance.tsdb.enable = true
canal.instance.gtidon = false
# 修改点:将此处值修改为源库的地址
canal.instance.master.address = 192.168.91.131:3306
canal.instance.master.journal.name =
canal.instance.master.position =
canal.instance.master.timestamp=
canal.instance.master.gtid=
# 修改点: 将此处的用户名、密码修改为源库对应的用户名、密码
canal.instance.dbUsername = root
canal.instance.dbPassword = root@123456
canal.instance.connectionCharset = UTF-8
canal.instance.enableDruid = false
canal.instance.filter.regex=.*\\..*
# 过滤控制台打印与配置表无关的日志信息
canal.instance.filter.black.regex=mysql\\.slave_.*
canal.mq.topic = example
canal.mq.partition = 0

说明:

1> configMap中的app.sh文件,主要是覆写了官方镜像中的app.sh文件,原因是因为我这里系统的用户名为 root,而官方镜像中的用户名为 admin,如果不覆写app.sh文件,会导致部署失败,具体失败原因可参看我的另一篇文章:https://www.cnblogs.com/cndarren/p/16746300.html

2> canal deployer挂载配置的路径与镜像中对应文件夹路径保持一致,镜像文件夹路径可参看:https://hub.docker.com/layers/canal/canal-server/latest/images/sha256-0d1018759efd92ad331c7cc379afa766c8d943ef48ef8d208ade646f54bf1565?context=explore

3.2、Canal adapter部署文件

---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: canal-adapter
name: canal-adapter
namespace: canal-mysql
spec:
replicas: 1
minReadySeconds: 10
selector:
matchLabels:
app: canal-adapter
template:
metadata:
name: canal-adapter
labels:
app: canal-adapter
spec:
volumes:
- name: conf
defaultMode: 420
configMap:
name: canal-adapter-configmap
containers:
- name: canal-adapter
image: funnyzak/canal-adapter:1.1.6
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /opt/canal/canal-adapter/conf/application.yml
name: conf
subPath: application.yml
- mountPath: /opt/canal/canal-adapter/conf/bootstrap.yml
name: conf
subPath: bootstrap.yml
- mountPath: /opt/canal/canal-adapter/conf/rdb/monitoralter.yml
name: conf
subPath: monitoralter.yml
ports:
- containerPort: 8081
protocol: TCP ---
apiVersion: v1
kind: ConfigMap
metadata:
name: canal-adapter-configmap
namespace: canal-mysql
data:
application.yml: |-
server:
port: 8081
logging:
level:
org.springframework: WARN
com.alibaba.otter.canal.client.adapter.rdb: WARN
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
default-property-inclusion: non_null
canal.conf:
mode: tcp
flatMessage: true
# 修改点:zookeeper服务对应的地址
zookeeperHosts: zookeeper:2181
syncBatchSize: 1000
retries: 0
timeout:
accessKey:
secretKey:
consumerProperties:
# 修改点:由于采用tcp方式,所以这里配置就是tcp方式下canal deployer对应的地址
canal.tcp.server.host: canal-deployer:11111
canal.tcp.zookeeper.hosts:
canal.tcp.batch.size: 500
canal.tcp.username:
canal.tcp.password:
# 修改点:源库数据源配置信息
srcDataSources:
monitorAlterDS:
url: jdbc:mysql://192.168.91.131:3306/monitor_alert?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
username: root
password: root@123456
# 修改点:目标库数据源配置信息
canalAdapters:
- instance: example
groups:
- groupId: g1
outerAdapters:
- name: logger
- name: rdb
key: mysql1
properties:
jdbc.driverClassName: com.mysql.jdbc.Driver
jdbc.url: jdbc:mysql://192.168.91.135:3306/monitor_alert?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
jdbc.username: root
jdbc.password: admin@4321
bootstrap.yml:
# 修改点:镜像方式同步配置文件
monitoralter.yml: |-
dataSourceKey: monitorAlterDS
destination: example
groupId: g1
outerAdapterKey: mysql1
concurrent: true
dbMapping:
mirrorDb: true
database: monitor_alert

说明:

1> canal adapter挂载配置的路径与镜像中对应文件夹路径保持一致,镜像文件夹路径可参看:https://hub.docker.com/layers/funnyzak/canal-adapter/1.1.6/images/sha256-1765db135c5e3610601f5680fa7d35f6b02f63218d8fdfe8b92d6371b1831190?context=explore

2> 如果有多个数据库下的数据表数据需要同步,可以在canal adapter的Deployment文件下添加对应的挂载的配置文件路径,然后再修改configMap文件即可,具体操作可参考如下所示

## 例如:需要再同步product数据库下的表数据
# Deployment文件修改如下:
# 1、canal adapter的Deployment文件添加挂载的product数据库信息
containers:
- name: canal-adapter
image: funnyzak/canal-adapter:1.1.6
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /opt/canal/canal-adapter/conf/application.yml
name: conf
subPath: application.yml
- mountPath: /opt/canal/canal-adapter/conf/bootstrap.yml
name: conf
subPath: bootstrap.yml
- mountPath: /opt/canal/canal-adapter/conf/rdb/monitoralter.yml
name: conf
subPath: monitoralter.yml
- mountPath: /opt/canal/canal-adapter/conf/rdb/product.yml
name: conf
subPath: product.yml # configMap修改如下:
# 1、application.yml文件添加源库、目标库的地址信息
# 源库信息
srcDataSources:
monitorAlterDS:
url: jdbc:mysql://192.168.91.131:3306/monitor_alert?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
username: root
password: root@123456
productDS:
url: jdbc:mysql://192.168.91.131:3306/product?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
username: root
password: root@123456
# 目标库信息
canalAdapters:
- instance: example
groups:
- groupId: g1
outerAdapters:
- name: logger
- name: rdb
key: mysql1
properties:
jdbc.driverClassName: com.mysql.jdbc.Driver
jdbc.url: jdbc:mysql://192.168.91.135:3306/monitor_alert?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
jdbc.username: root
jdbc.password: admin@4321
- name: rdb
key: mysql2
properties:
jdbc.driverClassName: com.mysql.jdbc.Driver
jdbc.url: jdbc:mysql://192.168.91.135:3306/product?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
jdbc.username: root
jdbc.password: admin@4321
# 2、添加对应的挂载配置文件product.yml
product.yml: |-
dataSourceKey: productDS
destination: example
groupId: g1
outerAdapterKey: mysql2
concurrent: true
dbMapping:
mirrorDb: true
database: product

3> 关于bootstrap.yml文件,这里并没有具体内容,原因仅是将canal adapter镜像中的bootstrap.yml内容进行注释,主要原因是canal adapter部署时并没有用到对应的canal_manager数据库配置,如果不覆写,会导致canal adapter部署启动时报连接不上canal_manager数据库的异常,具体问题可参看相关issue(https://github.com/alibaba/canal/issues/4197

3.3、Zookeeper部署文件

---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: zk-deployment
name: zookeeper
namespace: canal-mysql
spec:
replicas: 2
selector:
matchLabels:
app: zk
template:
metadata:
name: zk
labels:
app: zk
spec:
volumes:
- name: localtime
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
containers:
- name: zookeeper
image: zookeeper:3.6.2
imagePullPolicy: IfNotPresent
volumeMounts:
- name: localtime
mountPath: /etc/localtime
readOnly: true ---
kind: Service
apiVersion: v1
metadata:
name: zookeeper
namespace: canal-mysql
labels:
app: zk
spec:
ports:
- port: 2181
name: client
clusterIP: None
selector:
app: zk

4、部署成功图

4.1、Canal Deployer部署成功图

4.2、Canal Adapter部署成功图

k8s部署canal-1.1.6版本实现MySQL数据库数据同步的更多相关文章

  1. 在Linux环境下,将Solr部署到tomcat7中,导入Mysql数据库数据, 定时更新索引

    什么是solr solr是基于Lucene的全文搜索服务器,对Lucene进行了扩展优化. 准备工作 首先,去下载以下软件包: JDK8:jdk-8u60-linux-x64.tar.gz TOMCA ...

  2. MySQL JDBC驱动版本与MySQL数据库版本对应关系

    前言:前段时间发现在家使用和公司一样的mysql jdbc驱动版本发生了异常,原因:家里mysql数据库版本与公司不一致导致.查询了相关资料,发现mysql jdbc驱动版本与mysql数据库版本有一 ...

  3. 在win10系统安装两个不同版本的mySQL数据库

    我们项目用的mySQL数据库,为了回家看代码方便,于是在本地安装mySQL数据库,一开始安装了比服务器mySQL5.7.24更高版本的mySQL8.0.11,结果项目启动报错,估计是版本太高项目中引入 ...

  4. 在windows上安装不同(两个)版本的Mysql数据库

    1.起因: 需要导入一个sql文件,发现死活导不进去.当执行到这一句时,就有问题.经过一番搜索,原来是我的数据库版本(原先Mysql版本5.5)低了,而支持该语句的版本应该是至少要5.7.那我索性就去 ...

  5. mysql使用yum源安装各个版本的mysql数据库

    每次想用yum安装旧版本的mysql时,发现都找不到mysql的yum安装源,在官网只能找到最新版本mysql的yum源.后来才知道,原来最新的mysql的yum源也是包含了旧版本的mysql的yum ...

  6. ABP (.Net Core 3.1版本) 使用MySQL数据库迁移启动模板项目(1)

    最近要搭建新项目,因为还没有用过.net core,所以想用.net core的环境搭建新项目,因为不熟悉.net core的架构,所以就下载了abp项目先了解一下. 因为自己太菜了,下载了模板项目, ...

  7. windows上同时安装两个版本的mysql数据库

    一.先停止之前安装的低版本mysql服务 二.将其他电脑上安装好的mysql拷贝过来 三.拷贝过来之后,进入该文件夹,删除掉data目录,然后打开my.ini,进行修改端口号,端口号改为3307,ba ...

  8. 使用docker部署nginx+tomcat架构(2):访问mysql数据库

    上一篇完成了通过docker部署nginx+tomcat的基础软件架构,但是距离一个真正可用的软件架构还差得很远.其中最重要的一点是缺少数据库这个角色的存在,那么本篇就来完善这一点. 废话少说,直接进 ...

  9. 使用Canal作为mysql的数据同步工具

    一.Canal介绍 1.应用场景 在前面的统计分析功能中,我们采取了服务调用获取统计数据,这样耦合度高,效率相对较低,目前我采取另一种实现方式,通过实时同步数据库表的方式实现,例如我们要统计每天注册与 ...

  10. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 大型软件系统客户端数据同步的问题解决

    作为一个完整的整体信息化解决方案需要有足够强大的各种功能,这些功能相对独立,又互相依存.当有需要这样的功能时可以随时拿出来用,适当修改一下就可以满足要求.只有这样才能快速开发各种信息化系统,才能满足各 ...

随机推荐

  1. python-代码编程规范

    命名 常用简写 名称相关 # 信息 information: info # 功能 function : func # 数量 quantity:qty PYQT相关 button : btn_ chec ...

  2. 支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 前文链接 支持JDK19虚拟线程的web框架,之一:体 ...

  3. Go语言核心36讲23

    我在上两篇文章中,详细地讲述了Go语言中的错误处理,并从两个视角为你总结了错误类型.错误值的处理技巧和设计方式. 在本篇,我要给你展示Go语言的另外一种错误处理方式.不过,严格来说,它处理的不是错误, ...

  4. 树莓派(香橙派)通过.NET IoT 操作SPI编写屏幕驱动 顺手做个四足机器人(一)

    摘要 这片文章主要是记录自己的整活过程,涉及到的技术包括.NET IoT, .NET Web, .NET MAUI,框架采用的也是最新的.NET 7. 本人是用的树莓派Zero 2 W(ubuntu- ...

  5. UBOOT编译--- UBOOT的顶层config.mk(五)

    1. 前言 UBOOT版本:uboot2018.03,开发板myimx8mmek240. 2. 概述 此文件包含在 ./Makefile 和 spl/Makefile 中. 清理状态以避免添加两次相同 ...

  6. DLR 的扩展库 Dynamitey

    .NET 在 CLR 对动态语言或者脚本语言的支持是通过DLR 完成的, Miguel de Icaza对 DLR 的特点概括如下: 一个针对动态语言的共享式类型系统: 一个共享的 AST,可以被语言 ...

  7. 使用.NET7和C#11打造最快的序列化程序-以MemoryPack为例

    译者注 本文是一篇不可多得的好文,MemoryPack 的作者 neuecc 大佬通过本文解释了他是如何将序列化程序性能提升到极致的:其中从很多方面(可变长度.字符串.集合等)解释了一些性能优化的技巧 ...

  8. 【离线数仓】Day03-系统业务数据仓库:数仓表概念、搭建、数据导入、数据可视化、Azkaban全调度、拉链表的使用

    一.电商业务与数据结构简介 1.业务流程 2.常识:SKU/SPU SKU=Stock Keeping Unit(库存量基本单位).现在已经被引申为产品统一编号的简称,每种产品均对应有唯一的SKU号. ...

  9. 常用函数/异常处理/for循环本质

    常用内置函数 1,map() - 映射 格式: map(函数,可遍历对象) 指将遍历的元素挨个取出来做函数的行参传参,得到的返回值全部放回map工厂中,map工厂可以被转换成列表查看到 每一个被函数处 ...

  10. ChatGPT 会开源吗?

    最近,我被一款叫做 ChatGPT 的人工智能(AI)聊天机器人,刷屏了.网上有人说它是搜索引擎杀手,还有人说它将取代程序员... 最后,我还是没扛住铺天盖地的赞美,跑去注册了个账号,抱着调侃&quo ...