• GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。

1. 需求背景与万里安全数据库软件GreatDB分布式部署模式介绍

1.1 需求背景

混沌测试是检测分布式系统不确定性、建立系统弹性信心的一种非常好的方式,因此我们采用开源工具Chaos Mesh来做GreatDB分布式集群的混沌测试。

1.2 万里安全数据库软件GreatDB分布式部署模式介绍

万里安全数据库软件GreatDB 是一款关系型数据库软件,同时支持集中式和分布式的部署方式,本文涉及的是分布式部署方式。

分布式部署模式采用shared-nothing架构;通过数据冗余与副本管理确保数据库无单点故障;数据sharding与分布式并行计算实现数据库系统高性能;可无限制动态扩展数据节点,满足业务需要。

整体架构如下图所示:

2. 环境准备

2.1 Chaos Mesh安装

在安装Chaos Mesh之前请确保已经预先安装了helm,docker,并准备好了一个kubernetes环境。

1)在 Helm 仓库中添加 Chaos Mesh 仓库:

helm repo add chaos-mesh https://charts.chaos-mesh.org

2)查看可以安装的 Chaos Mesh 版本:

helm search repo chaos-mesh

3)创建安装 Chaos Mesh 的命名空间:

kubectl create ns chaos-testing

4)在docker环境下安装Chaos Mesh:

helm install chaos-mesh chaos-mesh/chaos-mesh -n=chaos-testing

验证安装 执行以下命令查看Chaos Mesh的运行情况:

kubectl get pod -n chaos-testing

下面是预期输出:

NAME                                       READY   STATUS    RESTARTS   AGE
chaos-controller-manager-d7bc9ccb5-dbccq   1/1     Running   0          26d
chaos-daemon-pzxc7                         1/1     Running   0          26d
chaos-dashboard-5887f7559b-kgz46           1/1     Running   1          26d

如果3个pod的状态都是Running,表示 Chaos Mesh 已经成功安装。

2.2 准备测试需要的镜像

2.2.1 准备mysql镜像

一般情况下,mysql使用官方5.7版本的镜像,mysql监控采集器使用的是mysqld-exporter,也可以直接从docker hub下载:

docker pull mysql:5.7
docker pull prom/mysqld-exporter

2.2.2 准备zookeeper镜像

zookeeper使用的是官方3.5.5版本镜像,zookeeper组件涉及的监控有jmx-prometheus-exporter 和zookeeper-exporter,均从docker hub下载:

docker pull zookeeper:3.5.5
docker pull sscaling/jmx-prometheus-exporter
docker pull josdotso/zookeeper-exporter

2.2.3 准备GreatDB镜像 选择一个GreatDB的tar包,将其解压得到一个./greatdb目录,再将greatdb-service-docker.sh文件拷贝到这个解压出来的./greatdb目录里:

cp greatdb-service-docker.sh ./greatdb/

将greatdb Dockerfile放到./greatdb文件夹的同级目录下,然后执行以下命令构建GreatDB镜像:

docker build -t greatdb/greatdb:tag2021 .

2.2.4 准备GreatDB分布式集群部署/清理的镜像

下载集群部署脚本cluster-setup,集群初始化脚本init-zk 以及集群helm charts包(可咨询4.0开发/测试组获取)

将上述材料放在同一目录下,编写如下Dockerfile:

FROM debian:buster-slim as init-zkCOPY ./init-zk /root/init-zk
RUN chmod +x /root/init-zkFROM debian:buster-slim as cluster-setup
\# Set aliyun repo for speed
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.listRUN apt-get -y update && \apt-get -y install \curl \wgetRUN curl -L https://storage.googleapis.com/kubernetes-release/release/v1.20.1/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl && \chmod +x /usr/local/bin/kubectl && \mkdir /root/.kube && \wget https://get.helm.sh/helm-v3.5.3-linux-amd64.tar.gz && \tar -zxvf helm-v3.5.3-linux-amd64.tar.gz && \mv linux-amd64/helm /usr/local/bin/helmCOPY ./config /root/.kube/
COPY ./helm /helm
COPY ./cluster-setup /

执行以下命令构建所需镜像:

docker build --target init-zk -t greatdb/initzk:latest .docker build --target cluster-setup -t greatdb/cluster-setup:v1 .

2.2.5 准备测试用例的镜像 目前测试支持的用例有:bank,bank2,pbank,tpcc,flashback等,每个用例都是一个可执行文件。

以flashback测例为例构建测试用例的镜像,先将用例下载到本地,在用例的同一目录下编写如下内容的Dockerfile:

FROM debian:buster-slim
COPY ./flashback /
RUN cd / && chmod +x ./flashback

执行以下命令构建测试用例镜像:

docker build -t greatdb/testsuite-flashback:v1 .

2.3 将准备好的镜像上传到私有仓库中

创建私有仓库和上传镜像操作请参考:https://zhuanlan.zhihu.com/p/78543733

3. Chaos Mesh的使用

3.1 搭建GreatDB分布式集群

在上一章2.2.4 中cluster-setup目录下执行以下命令块去搭建测试集群:

./cluster-setup  \
-clustername=c0 \
-namespace=test \
-enable-monitor=true \
-mysql-image=mysql:5.7 \
-mysql-replica=3 \
-mysql-auth=1 \
-mysql-normal=1 \
-mysql-global=1 \
-mysql-partition=1 \
-zookeeper-repository=zookeeper \
-zookeeper-tag=3.5.5 \
-zookeeper-replica=3 \
-greatdb-repository=greatdb/greatdb \
-greatdb-tag=tag202110 \
-greatdb-replica=3 \
-greatdb-serviceHost=172.16.70.249

输出信息:

liuxinle@liuxinle-OptiPlex-5060:~/k8s/cluster-setup$ ./cluster-setup \
> -clustername=c0 \
> -namespace=test \
> -enable-monitor=true \
> -mysql-image=mysql:5.7 \
> -mysql-replica=3 \
> -mysql-auth=1 \
> -mysql-normal=1 \
> -mysql-global=1 \
> -mysql-partition=1 \
> -zookeeper-repository=zookeeper \
> -zookeeper-tag=3.5.5 \
> -zookeeper-replica=3 \
> -greatdb-repository=greatdb/greatdb \
> -greatdb-tag=tag202110 \
> -greatdb-replica=3 \
> -greatdb-serviceHost=172.16.70.249
INFO[2021-10-14T10:41:52+08:00] SetUp the cluster ...                         NameSpace=test
INFO[2021-10-14T10:41:52+08:00] create namespace ...
INFO[2021-10-14T10:41:57+08:00] copy helm chart templates ...
INFO[2021-10-14T10:41:57+08:00] setup ...                                     Component=MySQL
INFO[2021-10-14T10:41:57+08:00] exec helm install and update greatdb-cfg.yaml ...
INFO[2021-10-14T10:42:00+08:00] waiting mysql pods running ...
INFO[2021-10-14T10:44:27+08:00] setup ...                                     Component=Zookeeper
INFO[2021-10-14T10:44:28+08:00] waiting zookeeper pods running ...
INFO[2021-10-14T10:46:59+08:00] update greatdb-cfg.yaml
INFO[2021-10-14T10:46:59+08:00] setup ...                                     Component=greatdb
INFO[2021-10-14T10:47:00+08:00] waiting greatdb pods running ...
INFO[2021-10-14T10:47:21+08:00] waiting cluster running ...
INFO[2021-10-14T10:47:27+08:00] waiting prometheus server running...
INFO[2021-10-14T10:47:27+08:00] Dump Cluster Info
INFO[2021-10-14T10:47:27+08:00] SetUp success.                                ClusterName=c0 NameSpace=test

看到c0-zookeeper-initzk-7hbfs的状态是Completed,其他pod的状态为Running,表示集群搭建成功。

3.2 在GreatDB分布式集群中使用Chaos Mesh做混沌测试

Chaos Mesh在kubernetes环境支持注入的故障类型包括:模拟Pod故障、模拟网络故障、模拟压力场景等,这里我们以模拟Pod故障中的pod-kill为例。

将实验配置写入到文件中 pod-kill.yaml,内容示例如下:

apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos   # 要注入的故障类型
metadata:name: pod-failure-examplenamespace: test   # 测试集群pod所在的namespace
spec:action: pod-kill   # 要注入的具体故障类型mode: all    # 指定实验的运行方式,all(表示选出所有符合条件的 Pod)duration: '30s'    # 指定实验的持续时间 selector: labelSelectors:"app.kubernetes.io/component": "greatdb"    # 指定注入故障目标pod的标签,通过kubectl describe pod c0-greatdb-1 -n test 命令返回结果中Labels后的内容得到

创建故障实验,命令如下:

kubectl create -n test -f pod-kill.yaml

创建完故障实验之后,执行命令 kubectl get pod -n test -o wide 结果如下:

NAME                                    READY   STATUS              RESTARTS   AGE     IP             NODE                     NOMINATED NODE   READINESS GATES
c0-auth0-mysql-0                        2/2     Running             0          14m     10.244.87.18   liuxinle-optiplex-5060   <none>           <none>
c0-auth0-mysql-1                        2/2     Running             0          14m     10.244.87.54   liuxinle-optiplex-5060   <none>           <none>
c0-auth0-mysql-2                        2/2     Running             0          13m     10.244.87.57   liuxinle-optiplex-5060   <none>           <none>
c0-greatdb-0                            0/2     ContainerCreating   0          2s      <none>         liuxinle-optiplex-5060   <none>           <none>
c0-greatdb-1                            0/2     ContainerCreating   0          2s      <none>         liuxinle-optiplex-5060   <none>           <none>
c0-glob0-mysql-0                        2/2     Running             0          14m     10.244.87.51   liuxinle-optiplex-5060   <none>           <none>
c0-glob0-mysql-1                        2/2     Running             0          14m     10.244.87.41   liuxinle-optiplex-5060   <none>           <none>
c0-glob0-mysql-2                        2/2     Running             0          13m     10.244.87.60   liuxinle-optiplex-5060   <none>           <none>
c0-nor0-mysql-0                         2/2     Running             0          14m     10.244.87.29   liuxinle-optiplex-5060   <none>           <none>
c0-nor0-mysql-1                         2/2     Running             0          14m     10.244.87.4    liuxinle-optiplex-5060   <none>           <none>
c0-nor0-mysql-2                         2/2     Running             0          13m     10.244.87.25   liuxinle-optiplex-5060   <none>           <none>
c0-par0-mysql-0                         2/2     Running             0          14m     10.244.87.55   liuxinle-optiplex-5060   <none>           <none>
c0-par0-mysql-1                         2/2     Running             0          14m     10.244.87.13   liuxinle-optiplex-5060   <none>           <none>
c0-par0-mysql-2                         2/2     Running             0          13m     10.244.87.21   liuxinle-optiplex-5060   <none>           <none>
c0-prometheus-server-6697649b76-fkvh9   2/2     Running             0          9m24s   10.244.87.37   liuxinle-optiplex-5060   <none>           <none>
c0-zookeeper-0                          1/1     Running             1          12m     10.244.87.44   liuxinle-optiplex-5060   <none>           <none>
c0-zookeeper-1                          1/1     Running             0          11m     10.244.87.30   liuxinle-optiplex-5060   <none>           <none>
c0-zookeeper-2                          1/1     Running             0          10m     10.244.87.49   liuxinle-optiplex-5060   <none>           <none>
c0-zookeeper-initzk-7hbfs               0/1     Completed           0          12m     10.244.87.17   liuxinle-optiplex-5060   <none>           <none>

4. 在argo中编排测试流程

Argo 是一个开源的容器本地工作流引擎,用于在Kubernetes上完成工作,可以将多步骤工作流建模为一系列任务,完成测试流程编排。

我们使用argo定义一个测试任务,基本的测试流程是固定的,如下所示:

测试流程的step1是部署测试集群,接着开启两个并行任务,step2跑测试用例,模拟业务场景,step3同时使用Chaos Mesh注入故障,step2的测试用例执行结束之后,step4终止故障注入,最后step5清理集群环境。

4.1 用argo编排一个混沌测试工作流(以flashback测试用例为例)

1)修改 cluster-setup.yaml 中的image信息,改成步骤2.2 准备测试需要的镜像中自己传上去的集群部署/清理镜像名和tag

2)修改 testsuite-flashback.yaml 中的image信息,改成步骤2.2 准备测试需要的镜像中自己传上去的测试用例镜像名和tag

3)将集群部署、测试用例和工具模板的yaml文件全部使用 kubectl apply -n argo -f xxx.yaml 命令创建资源 (这些文件定义了一些argo template,方便用户写workflow时候使用)

kubectl apply -n argo -f cluster-setup.yaml
kubectl apply -n argo -f testsuite-flashback.yaml
kubectl apply -n argo -f tools-template.yaml

4)复制一份workflow模板文件 workflow-template.yaml,将模板文件中注释提示的部分修改为自己的设置即可,然后执行以下命令创建混沌测试工作流:

kubectl apply -n argo -f workflow-template.yaml

以下是一份workflow模板文件:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:generateName: chaostest-c0-0-name: chaostest-c0-0namespace: argo
spec:entrypoint: test-entry #测试入口,在这里传入测试参数,填写clustername、namespace、host、greatdb镜像名和tag名等基本信息serviceAccountName: argoarguments:parameters:- name: clusternamevalue: c0- name: namespacevalue: test- name: hostvalue: 172.16.70.249- name: portvalue: 30901- name: passwordvalue: Bgview@2020- name: uservalue: root- name: run-timevalue: 10m- name: greatdb-repositoryvalue: greatdb/greatdb- name: greatdb-tagvalue: tag202110- name: nemesisvalue: kill_mysql_normal_master,kill_mysql_normal_slave,kill_mysql_partition_master,kill_mysql_partition_slave,kill_mysql_auth_master,kill_mysql_auth_slave,kill_mysql_global_master,kill_mysql_global_slave,kill_mysql_master,kill_mysql_slave,net_partition_mysql_normal,net_partition_mysql_partition,net_partition_mysql_auth,net_partition_mysql_global- name: mysql-partitionvalue: 1- name: mysql-globalvalue: 1- name: mysql-authvalue: 1- name: mysql-normalvalue: 2templates:- name: test-entrysteps:- - name: setup-greatdb-cluster  # step.1 集群部署. 请指定正确的参数,主要是mysql和zookeeper的镜像名、tag名templateRef:name: cluster-setup-templatetemplate: cluster-setuparguments:parameters:- name: namespacevalue: "{{workflow.parameters.namespace}}"- name: clusternamevalue: "{{workflow.parameters.clustername}}"- name: mysql-imagevalue: mysql:5.7.34- name: mysql-replicavalue: 3- name: mysql-authvalue: "{{workflow.parameters.mysql-auth}}"- name: mysql-normalvalue: "{{workflow.parameters.mysql-normal}}"- name: mysql-partitionvalue: "{{workflow.parameters.mysql-partition}}"- name: mysql-globalvalue: "{{workflow.parameters.mysql-global}}"- name: enable-monitorvalue: false- name: zookeeper-repositoryvalue: zookeeper- name: zookeeper-tagvalue: 3.5.5- name: zookeeper-replicavalue: 3- name: greatdb-repositoryvalue: "{{workflow.parameters.greatdb-repository}}"- name: greatdb-tagvalue: "{{workflow.parameters.greatdb-tag}}"- name: greatdb-replicavalue: 3- name: greatdb-serviceHostvalue: "{{workflow.parameters.host}}"- name: greatdb-servicePortvalue: "{{workflow.parameters.port}}"- - name: run-flashbacktest    # step.2 运行测试用例,请替换为你要运行的测试用例template并指定正确的参数,主要是测试使用的表个数和大小templateRef:name: flashback-test-templatetemplate: flashbackarguments:parameters:- name: uservalue: "{{workflow.parameters.user}}"- name: passwordvalue: "{{workflow.parameters.password}}"- name: hostvalue: "{{workflow.parameters.host}}"- name: portvalue: "{{workflow.parameters.port}}"- name: concurrencyvalue: 16- name: sizevalue: 10000- name: tablesvalue: 10- name: run-timevalue: "{{workflow.parameters.run-time}}"- name: single-statementvalue: true- name: manage-statementvalue: true- name: invoke-chaos-for-flashabck-test    # step.3 注入故障,请指定正确的参数,这里run-time和interval分别定义了故障注入的时间和频次,因此省略掉了终止故障注入步骤templateRef:name: chaos-rto-templatetemplate: chaos-rtoarguments:parameters:- name: uservalue: "{{workflow.parameters.user}}"- name: hostvalue: "{{workflow.parameters.host}}"- name: passwordvalue: "{{workflow.parameters.password}}"- name: portvalue: "{{workflow.parameters.port}}"- name: k8s-configvalue: /root/.kube/config- name: namespacevalue: "{{workflow.parameters.namespace}}"- name: clusternamevalue: "{{workflow.parameters.clustername}}"- name: prometheusvalue: ''- name: greatdb-jobvalue: greatdb-monitor-greatdb- name: nemesisvalue: "{{workflow.parameters.nemesis}}"- name: nemesis-durationvalue: 1m- name: nemesis-modevalue: default- name: wait-timevalue: 5m- name: check-timevalue: 5m- name: nemesis-scopevalue: 1- name: nemesis-logvalue: true- name: enable-monitorvalue: false- name: run-timevalue: "{{workflow.parameters.run-time}}"- name: intervalvalue: 1m- name: monitor-logvalue: false- name: enable-rtovalue: false- name: rto-qpsvalue: 0.1- name: rto-warmvalue: 5m- name: rto-timevalue: 1m- name: log-levelvalue: debug- - name: flashbacktest-output         # 输出测试用例是否通过的结果templateRef:name: tools-templatetemplate: output-resultarguments:parameters:- name: infovalue: "flashback test pass, with nemesis: {{workflow.parameters.nemesis}}"- - name: clean-greatdb-cluster           # step.4 清理测试集群,这里的参数和step.1的参数一致templateRef:name: cluster-setup-templatetemplate: cluster-setuparguments:parameters:- name: namespacevalue: "{{workflow.parameters.namespace}}"- name: clusternamevalue: "{{workflow.parameters.clustername}}"- name: mysql-imagevalue: mysql:5.7- name: mysql-replicavalue: 3- name: mysql-authvalue: "{{workflow.parameters.mysql-auth}}"- name: mysql-normalvalue: "{{workflow.parameters.mysql-normal}}"- name: mysql-partitionvalue: "{{workflow.parameters.mysql-partition}}"- name: mysql-globalvalue: "{{workflow.parameters.mysql-global}}"- name: enable-monitorvalue: false- name: zookeeper-repositoryvalue: zookeeper- name: zookeeper-tagvalue: 3.5.5- name: zookeeper-replicavalue: 3- name: greatdb-repositoryvalue: "{{workflow.parameters.greatdb-repository}}"- name: greatdb-tagvalue: "{{workflow.parameters.greatdb-tag}}"- name: greatdb-replicavalue: 3- name: greatdb-serviceHostvalue: "{{workflow.parameters.host}}"- name: greatdb-servicePortvalue: "{{workflow.parameters.port}}"- name: cleanvalue: true- - name: echo-resulttemplateRef:name: tools-templatetemplate: echoarguments:parameters:- name: infovalue: "{{item}}"withItems:- "{{steps.flashbacktest-output.outputs.parameters.result}}"

Enjoy GreatSQL :)

文章推荐:

GreatSQL MGR FAQ https://mp.weixin.qq.com/s/J6wkUpGXw3YkyEUJXiZ9xA

万答#12,MGR整个集群挂掉后,如何才能自动选主,不用手动干预 https://mp.weixin.qq.com/s/07o1poO44zwQIvaJNKEoPA

『2021数据技术嘉年华·ON LINE』:《MySQL高可用架构演进及实践》 https://mp.weixin.qq.com/s/u7k99y6i7riq7ScYs7ySnA

一条sql语句慢在哪之抓包分析 https://mp.weixin.qq.com/s/AYibbzl860D90rOeyjB6IQ

万答#15,都有哪些情况可能导致MGR服务无法启动 https://mp.weixin.qq.com/s/inSGpd0Q_XIl2Mb-VsvNsA

技术分享 | 为什么MGR一致性模式不推荐AFTER https://mp.weixin.qq.com/s/rNeq479RNsklY1BlfKOsYg

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

Gitee: https://gitee.com/GreatSQL/GreatSQL

GitHub: https://github.com/GreatSQL/GreatSQL

Bilibili: https://space.bilibili.com/1363850082/video

微信&QQ群: 可搜索添加GreatSQL社区助手微信好友,发送验证信息“加群”加入GreatSQL/MGR交流微信群

QQ群:533341697 微信小助手:wanlidbc

本文由博客一文多发平台 OpenWrite 发布!

技术分享 | 在GreatDB分布式部署模式中使用Chaos Mesh做混沌测试相关推荐

  1. Chaos Mesh 实战分享丨通过混沌工程验证 GreatDB 分布式部署模式的稳定性

    Chaos Mesh 最初作为开源分布式数据库 TiDB 的测试平台而创建,是一个多功能混沌工程平台,通过混沌测试验证分布式系统的稳定性.本文以万里安全数据库软件 GreatDB 分布式部署模式为例, ...

  2. SCOM 2012知识分享-26:分布式部署要点总结

    适应平台:System Center 2012 R2 Operations Manager+Windows Server 2012 R2 Update+SQL Server 2012 SP1 ---- ...

  3. 技术分享 | 客户分类管理模型在行业中的实践

    编者按:随着市场经济深入发展,社会对企业的要求逐步提高.秉持从客户出发.为客户创造价值的理念,才能有效提升企业核心竞争力,从而获取更多利益.在此背景下,客户关系管理愈发重要. 客户分类模型是客户关系管 ...

  4. 技术分享电商 API 获取商品详情返回值说明(可测试)

    item_get-取商品详情 公共参数 API工具 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中)注册Key和secret测试 secret Strin ...

  5. arm oe linux gnueabi 系统,【技术分享】Quectel 4G模块Opencpu中实现高通wifi功能

    导语 越来越多的IOT应用场景中需要使用4G模块,而在有些特定的场合需要把4G上网能力转化wifi功能,比如说无人机中视频传输,以及打印机行业中都有类似的应用案例,以便更好的提供给更多的客户端去使用. ...

  6. 技术分享 | 如何发现企业云网络中的安全隐患

    前言: 网络安全是云中心运维工作中重要的一项工作.有一家云计算网络公司,在过去的两年里,每年都会发生网络安全事件,给工程师和业务用户造成了不小的麻烦,那么痛定思痛,造成这些事件的原因是什么?如何&qu ...

  7. 技术分享 | 如何在 IAR和 KEIL中计算 CRC值

    前言 市面上越来越多的产品对其使用提出了安全要求,如何避免使用过程中对操作者带来危险,或者降低这种危险发生的概率,这都是产品安全性需要考虑的.鉴于此,相关产品需要通过相关行业的安全认证才能生产上市.针 ...

  8. 契约测试(中):利用PACT做契约测试

    软件质量保障 阿里巴巴资深测试开发工程师,工作重点为微服务测试.接口测试平台研发等. 主要分享软件测试以及测试开发博文,记录工作中的所思所获,介绍互联网大厂测试基建相关技术. 针对契约测试市面上提供了 ...

  9. 技术分享 | 混合云模式下SaaS端前端最佳实践

    导读:集成开放平台采用的是混合云部署架构,包含两个大的组件,管理控制台和引擎.管理控制台是SaaS的,部署在公有云,按租户隔离.引擎部署在客户私有云.一套SaaS版的管理控制台如何适配不同客户的引擎, ...

最新文章

  1. 35 个 Java 代码性能优化总结
  2. 从MVC到云原生:CBU研发体系演进之路
  3. python双向索引什么意思_python字典支持双向索引吗
  4. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 27丨每次访问的交易次数【难度困难-提前放出来】​
  5. mysql的增_MySQL之增_insert-replace
  6. 东莞理工学院计算机ccf,中国计算机学会东莞分部成立
  7. 你真的了解load方法么?(转载)
  8. 基于linux的电子邮件服务(sendmail)
  9. pytorch orchvision.transforms.Normalize
  10. 天上地下,马斯克和贝佐斯终有一战?
  11. java 按分割为数组中_[Java教程]JS中,split()用法(将字符串按指定符号分割成数组)...
  12. python牛顿迭代法求平方根_Python编程如何实现二分法及牛顿迭代法求平方根代码...
  13. 数学建模MATLAB之分析法(一)
  14. DM数据库密码策略和登录限制设置
  15. Vue脚手架搭建以及创建Vue项目流程
  16. 鸿蒙系统是电脑还是手机,鸿蒙系统什么时候能用在电脑上,华为鸿蒙系统什么时候能用...
  17. springboot+vue医院预约挂号系统java
  18. excel查重技巧:如何用组合函数快速统计重复数据(下)
  19. 谷歌浏览器拓展及脚本安装入门简介
  20. C++20新特性概览

热门文章

  1. jieba:我虽然结巴,但是我会分词啊
  2. stc8a_步进电机控制,加减速
  3. 5V单片机和3.3V模块接口通信
  4. 74HC595D介绍与实现(C语言与verilog实现)
  5. 《强化学习周刊》第22期:ICRA 2021-2022强化学习的最新研究与应用
  6. 1550 - 【提高】房屋积水
  7. 优化关键词,实现排名优势!
  8. Django Vue 跨域问题
  9. Linux的校园任我行与微软的校园先锋计划
  10. 线程池与Android的日日夜夜