OceanBase 中,如何抓包分析应用连接超时的问题
本文作者:胡呈清,爱可生 DBA 团队成员,擅长故障分析、性能优化
与MySQL这类单机数据库相比,OceanBase分布式数据库的访问链路相对较长,因此在遇到连接异常时,排查过程需要额外考虑更多环节。接下来,我们将通过一个具体案例,探讨在OceanBase中,如何抓包分析并解决应用连接超时的问题。
案例问题描述
这是一个生产环境,访问链路大概是这样的:
应用 -> VIP -> 3 节点 OBProxy -> 3 节点 OBServer
其中,VIP 是用 keepalived 来进行漂移的,所用版本为 OBServer 4.2.1.1、OBProxy 4.2.2.0。应用偶尔会出现连接数据库超时的报错:pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on ' xx.xx.xx.9' (timed out)"
,大概每天 1-2 次,日志如下:
分析过程
1. 分析 OBProxy 日志
思路 1:VIP 在 xx.xx.xx.12 绑在这个 OBProxy 节点上,所以所有应用访问 xx.xx.xx.9:3306 时实际上都是访问的 xx.xx.xx.12,因此先分析 xx.xx.xx.12 节点上的 obproxy.log 即可。
思路 2:分析 OBProxy 日志的目的是什么?
- 是看应用到 OBProxy 的前端连接处理是不是异常了。
- 如果应用到 OBProxy 连接正常,继续看 OBProxy 到 OBServer 的后端连接是不是建成功了。
由于日志回收,只保留了 03-11 08:14 这个时间段的日志。按照上述思路通过以下几个维度搜索日志:
- 过滤 VC_EVENT_EOS 关键字,看有没有异常断开的前端连接。结果返回空,说明没有。
grep VC_EVENT_EOS obproxy.log.* |egrep -i 'tenant_name=[a-z].*'
- 继续看 OBProxy 到 OBServer 的后端连接状况。这里需要用一点统计方法,先过滤 03-11 08:14 时间点来自客户端 xx.xx.xx.12 访问 xx.xx.xx.9:3306 的请求,将客户端 IP:PORT 输出出来。
grep 'xx.xx.xx.9:3306' obproxy.log.20240311084410 |egrep '2024-03-11 08:14:[0-2].*' | egrep 'caddr=\{xx.xx.xx.12' | awk -F'caddr={' '{print $2}' |awk -F'}' '{print $1}'
- 然后过滤 succ to set proxy_sessid 事件。这个事件说明连接建立成功,输出内容与上一步完全一致,说明所有连接都正常。
grep 'succ to set proxy_sessid' obproxy.log.20240311084410 | egrep '2024-03-11 08:14:[0-2].*' | awk -F'client_addr=' '{print $2}' |awk -F'"' '{print $2}' |grep 'xx.xx.xx.12'
- 继续输出创建连接成功后
server_sessid
,输出结果全部不为 0。说明所有连接都正常建立了后端连接。
grep 'succ to set proxy_sessid' obproxy.log.20240311084410 | egrep '2024-03-11 08:14:[0-2].*' | egrep 'client_addr="xx.xx.xx.12' | awk -F'server_sessid=' '{print $2}' |awk -F',' '{print $1}'
小结
OBProxy 日志正常,大概率 OBProxy 没有收到应用端的请求,这个连接超时问题可能和网络有关。下一步的建议:在应用服务器上抓包。
2. 抓包分析
由于这是一个偶发问题,无法预期故障时间,因此只能长时间抓包,需要注意两个两点:
- 每个包文件不能太大,因此需要自动切换结果文件。
- 抓的包不宜过多,降低可能对系统的影响,因此需要尽可能过滤包。
本案例的抓包命令如下:
tcpdump -X -s 0 -C 50 -W 500 -Z root -i lo -w /tmp/cap/obproxy.cap host xx.xx.xx.9
参数解释
- 应用与 OBProxy 在同一台服务器上,抓包时需要指定回环接口
-i lo
。 -w /tmp/cap/obproxy.cap
指定结果文件路径。-C 50
表示结果文件满 50M 就自动切换新的文件。-W 500
表示一共 500 个结果文件,当写满 500 个会循环到第 1 个继续写。host xx.xx.xx.9
过滤访问 VIP 的网络包,减少抓宝数量。
发现 3.14 15:52:57 应用发生了报错:
既然抓到包了,现在面对的一个问题是怎么分析这些网络包,并找到我们需要的信息?
思路 3:利用 Wireshark 的专家信息(入口:分析 -> 专家信息)快速找到可能异常的包。
在 Note 中看到有重传(retransmission),我们只需要找 3306 端口的包就行,只有 4232 > 3306 这一个连接发生了重传:
然后点开第一个重传的包,也就是第 8517 号包,查看这个连接的所有包(操作:右键 -> 追踪流 -> TCP 流):
由于客户端、服务端在一台服务器上,所以上面展示的包有来有回。
从客户端的角度来看过程
- 15:52:47 向
xx.xx.xx.9:3306
发起 TCP 连接请求(三次握手的 SYN),即 8359 号包。 - 15:52:48 向
xx.xx.xx.9:3306
重发 8517 号 SYN 包,TCP Retransmission 表示重传,TCP Port numbers reused 表示端口重用(net.ipv4.tcp_tw_reuse=1
),这是 Wireshark 打的标记,因为和第一个 SYN 包的四元组一样。 - 15:52:50 继续重发 SYN 包,9075。
- 15:52:54 继续重发 SYN 包,10140。
服务端角度来看过程
- 15:52:47 向
1xx.xx.xx.12:4232
发 SYN+ACK 包,即 8360 号包。 - 15:52:48 重发 SYN、ACK 包,即 8517 号包。
- ...
这里面还有 ICMP 协议的包,信息是 Destination unreachable(Port unreachable),从前面的信息来看是服务端到客户端的 4232 端口发 SYN+ACK 包时报的,因此客户端没收到服务端的 ACK 包一直重发 SYN 包。
应用报错是在 15:52:57,也就是客户端发起 TCP 连接的 10 秒后,Connector/Python 默认的 connection_timeout 就是 10秒,这个是吻合的。应用报错 timeout 就是丢包重传导致的,但是为什么会丢包?
查到这里僵住了,直接原因有了,但是根因还差一步。好在随着下一次报错,问题迎来了转机。
3. 第二次抓包分析
时隔 13 天后在 3 月 22 日,我们再次抓到一个故障时间点的包。再次祭出 Wireshark 三板斧,问题包如下:
这个异常包简直和 3 月 9 日的一模一样,最重要的是连客户端使用的随机端口一样都是 4232。这还有啥好说的,直接拿着这个证据问了下网络部门,这回终于得到证实:
结论
网络禁止了 4232 端口外部访问,因此当客户端连接 OBProxy、或者 OBProxy 连接 OBServer 时使用了 4232 随机端口,服务端回包到 4232 端口将导致丢包无法建立连接。
解决方案
设置内核参数 ip_local_port_range
,限制服务器本地随机端口的范围,防止使用到被禁止的端口:
sysctl -w net.ipv4.ip_local_port_range="10000 60999"
小提示:在部署 OB 集群时,OBServer 服务器初始化时会自动设置 net.ipv4.ip_local_port_range = 3500 65535,需要格外注意网络策略是否会有影响。
相关文章:
OceanBase 中,如何抓包分析应用连接超时的问题
本文作者:胡呈清,爱可生 DBA 团队成员,擅长故障分析、性能优化 与MySQL这类单机数据库相比,OceanBase分布式数据库的访问链路相对较长,因此在遇到连接异常时,排查过程需要额外考虑更多环节。接下来…...
用uv管理python环境/项目(各种应用场景)
一、安装uv 有python的情况 pip install uvWindows powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"linux或macOS curl -LsSf https://astral.sh/uv/install.sh | sh二、换镜像源 uv不会读取pip的镜像源配置,所…...
Linux——进程(5)进程地址空间
先看一个程序和现象 预期现象是,子进程和父进程相互独立,子进程的gval是100,101,102....而父进程一直都是100. 结果我们并不意外,只是我们发现,父子进程的gval的地址是一样的,这有点颠覆我们的认…...
docker(1) -- centos镜像
1. 前言 我在WSL中运行的系统是ubuntu2024,并安装了docker,想要在docker中运行一个centos的系统。 2. 下载并运行镜像 # 下载centos最新版镜像 $ docker pull centos Using default tag: latest latest: Pulling from library/centos a1d0c7532777: P…...
Vitis 2024.1 无法正常编译custom ip的bug(因为Makefile里的wildcard)
现象:如果在vivado中,添加了自己的custom IP,比如AXI4 IP,那么在Vitis(2024.1)编译导出的原本的.xsa的时候,会构建build失败。报错代码是: "Compiling blank_test_ip..."…...
【源码阅读】多个函数抽象为类(实现各种类型文件转为PDF)
目录 一、原始函数二、类三、转换过程 一、原始函数 最开始就是写了几个函数(包括doc、excel、ppt类型的文件)转换为pdf,需要将这些函数形成一个类。相似的一类函数就可以组成一个实现特定功能的类 import subprocess import pandas as pd i…...
word插入Mathtype公式居中和自动更新
word插入公式自动更新 前提:安装Mathtype 1.word中查看页的宽度 出现如下 2.设置样式 出现这个窗口 给样式随便起个名字 3.修改样式 3.1 设置两个制表位 第二个 3.2 修改公式字体 如下所示 4. 修改公式格式 4.1在word中打开 Mathtype 4.2 修改公式的格式 变成…...
SpringSecurity配置(自定义认证过滤器)
文末有本篇文章的项目源码文件可供下载学习 在这个案例中,我们已经实现了自定义登录URI的操作,登录成功之后,我们再次访问后端中的API的时候要在请求头中携带token,此时的token是jwt字符串,我们需要将该jwt字符串进行解析,查看解析后的User对象是否处于登录状态.登录状态下,将…...
python字符级差异分析并生成 Word 报告 自然语言处理断句
import difflib from docx import Document from docx.shared import RGBColor from snownlp import SnowNLPdef analyze_char_differences(text_a, text_b):"""分析两个文本的字符级差异:param text_a: 第一个文本:param text_b: 第二个文本"""…...
企业级云MES全套源码,支持app、小程序、H5、台后管理端
企业级云MES全套源码,支持app、小程序、H5、台后管理端,全套源码 开发环境 技术架构:springboot vue-element-plus-admin 开发语言:Java 开发工具:idea 前端框架:vue.js 后端框架ÿ…...
使用GoldenGate完成SQLserver到Oracle的数据实时同步
一、环境准备 *项目**源环境**目标环境*操作系统CentOS Linux release 7.6CentOS Linux release 7.6IP地址192.168.3.92192.168.3.168数据库及版本SQLserver 2016Oracle 11.2.0.4.0GoldenGate用户oggoggGoldenGate版本12.3.0.2.012.3.0.2.0 二、OGG架构 GoldenGate v11 能够…...
【OpenCV C++】如何快速 高效的计算出图像中大于值的像素个数? 遍历比较吗? No,效率太低!那么如何更高效?
文章目录 1 问题2 分析3 代码实现 (两种方法实现)方法1: 使用cv::compare方法2: 使用cv::threshold3.2 compare和threshold 看起来都有二值化效果? 那么二者效率?4 compare函数解释4.1 参数解释4.2 底层行为规则4.3 应用示例4.4 典型应用场景1 问题 一幅图像的目标区域ROI…...
Golang | 每日一练 (6)
💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 Golang | 每日一练 (6)题目参考答案什么是内存逃逸&am…...
git clone, 算是解决可以访问github但无法clone的问题
本文的前提是使用了**且可以正常访问github 查看代理的端口 将其配置到git 首先查看git配置 git config --list然后添加配置,我这边使用的是Hiddfy默认的端口是12334,如果是clash应该是7890 git config --global http.proxy 127.0.0.1:12334其他 删除…...
SpringBoot项目controller层接收对应格式请求的相关RequestMapping配置
目录 (1) (2) (3) 注:此情况注意和(4)中情况进行区分 (4) 在几个springboot项目开发后,我总结了以下的一些常见的接收对应请求的…...
基于ssm学科竞赛小程序的设计及实现(源码+lw+部署文档+讲解),源码可白嫖!
摘要 随着信息时代的来临,过去的学科竞赛管理方式的缺点逐渐暴露,本次对过去的学科竞赛管理方式的缺点进行分析,采取计算机方式构建学科竞赛小程序。本文通过阅读相关文献,研究国内外相关技术,提出了一种关于竞赛信息…...
【论文笔记】VGGT-从2D感知3D:pose估计+稠密重建+点跟踪
VGG组联合Meta改进了dust3r,输入图片,输出对应的一系列3D属性,被CVPR2025收录! 1.abstract 我们提出了VGGT,一种前馈神经网络,能够直接从场景的一个、几个或数百个视角推断出所有关键的3D属性,…...
【大模型系列篇】硅基智能开源数字人模型HeyGem.ai,开启数字人时刻
硅基智能开源数字人模型HeyGem.ai, 1秒克隆生成4K视频, 支持离线多语言, 开源72小时狂揽1.3k星, 目前已经获得3.4k星。 硅基智能正式宣布在GitHub开源全球TOP级数字人模型,同时发布基于该模型的同名数字人工具硅基数字人克隆的本地安装包,这一举措标志着…...
腾讯云容器集群:节点可以访问公网,节点内的pod无法访问公网
腾讯云容器集群:节点可以访问公网,节点内的pod无法访问公网 curl https://www.baidu.com/index.htm参考链接:https://cloud.tencent.com/document/product/457/50356 sysctl -a|grep net.ipv4.conf.all.rp_filter sysctl -a|grep net.ipv4.c…...
Winform优化控件布局性能 SuspendLayout 和 ResumeLayout 方法详解
在Winform中,SuspendLayout 和 ResumeLayout 方法用于优化控件布局性能,适用于批量修改控件属性或动态调整控件时的场景。以下是具体使用方法和注意事项: 一、基本用法 1.调用 SuspendLayout() 在开始批量修改控件前,调用…...
基于Netty实现高性能HTTP服务的架构解析
一、HTTP协议基础 1.1 HTTP协议概述 HTTP(HyperText Transfer Protocol)作为现代Web应用的基石,是基于TCP/IP的应用层协议,具有以下核心特性: 请求/响应模型:客户端发起请求,服务端返回响应无…...
Sqlite下载、安装与数据库创建
Sqlite官网 https://www.sqlite.org/index.html 官方文档链接 https://www.sqlite.org/docs.html 官方文档是英文版的,如果想看中文的文档请参考 **菜鸟教程** 网站中的 **《Sqlite教程》:https://www.runoob.com/sqlite/sqlite-tutorial.html 官方下载…...
内网环境安装dlv,本地远程调试go
背景:内网环境(服务器)下安装dlv,本地通过dlv调试编译后的go代码。 可以配合观看: 【dlv远程调试-哔哩哔哩】 https://b23.tv/NqPZ5q9 内网安装dlv步骤 1、dlv安装: (我额服务器和内网的go都是1.21以上) # 先在有网络的环境下(…...
【使用 Element UI 实现手动上传文件:FormData 追加文件和其他参数,支持单文件覆盖上传】
在开发 Web 应用时,文件上传是一个常见的需求。Element UI 提供了强大的 el-upload 组件,可以轻松实现文件上传功能。本文将详细介绍如何使用 Element UI 实现以下功能: 手动触发文件上传:用户选择文件后,点击按钮手动…...
python基础8 单元测试
通过前面的7个章节,作者学习了python的各项基础知识,也学习了python的编译和执行。但在实际环境上,我们需要验证我们的代码功能符合我们的设计预期,所以需要结合python的单元测试类,编写单元测试代码。 Python有一个内…...
第四节:sqlx库使用指南
在项目中我们通常可能会使用database/sql连接MySQL数据库。本文借助使用sqlx实现批量插入数据的例子,介绍了sqlx中可能被你忽视了的sqlx.In和DB.NamedExec方法。 sqlx介绍 在项目中我们通常可能会使用database/sql连接MySQL数据库。sqlx可以认为是Go语言内置datab…...
麒麟操作系统作为服务器,并且需要在浏览器上调试 MATLAB
在内网环境下,使用麒麟操作系统作为服务器,并且需要在浏览器上调试 MATLAB 程序,这确实复杂,但仍然有可行的解决方案。麒麟操作系统是国产化的 Linux 发行版(如基于 Ubuntu Kylin 或银河麒麟),因…...
在线教育网站项目第四步:deepseek骗我, WSL2不能创建两个独立的Ubuntu,但我们能实现实例互访及外部访问
一、说明 上一章折腾了半天,搞出不少问题,今天我们在deepseek的帮助下,完成多个独立ubuntu24.04实例的安装,并完成固定ip,实践证明,deepseek不靠谱,浪费我2个小时时间,我们将在下面实…...
AI安全、大模型安全研究(DeepSeek)
DeepSeek 点燃AI应用革命之火,但安全 “灰犀牛” 正在逼近 DeepSeek-R1国产大模型的发布,以技术创新惊艳了全球,更是极致的性价比推动国内千行百业接入 AI,政府、企业竞速开发智能业务处理、智能客服、代码生成、营销文案等应用,“落地效率” 成为第一关键词。然而与此相…...
(hash表+vector 数位和相等数对的最大和)leetcode 2342
一定要断点调试看看数据对不对的上!!!不然很容易弄不清楚值和下标 这个题意思是在nums中找出相同数位和的值 如 数位和为7 nums中符合要求的有 43,7 在这些数中选两个相加取最大值,再与其他数位和取得的相加最大值比…...
正则表达式引擎深入探讨
正则表达式引擎(Regular Expression Engine)是正则表达式得以“活起来”的核心。它是一个精密的软件组件,负责接收正则表达式和输入文本,解析模式并执行匹配或替换操作,最终输出结果——可能是简单的“是否匹配”&…...
[蓝桥杯 2023 省 B] 飞机降落(不会dfs的看过来)
[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti 时刻到达机场上空,到达时它的剩余油料还可以继续盘旋 D i D_{i} Di 个单位时间,即它最早可以于 T i T_{i} Ti 时刻…...
DockerTLS加密/不加密传输
前言: 在Docker容器的网络通信中,安全性是至关重要的。DockerTLS作为一种加密传输协议,通过为Docker守护进程与客户端之间的通信提供加密层,有效防止数据在传输过程中被窃取或篡改。然而,在某些特定场景下,…...
基于微信小程序的充电桩管理系统
一、开发背景 在开发充电汽车管理系统之前,深入的需求分析至关重要。我们要充分了解不同用户群体的需求,比如私家车主希望充电过程便捷、高效、安全,能够实时查看充电状态和费用明细;出租车、网约车司机则更注重充电速度和充电桩…...
Excel导出工具类--复杂的excel功能导出(使用自定义注解导出)
Excel导出工具类 前言: 简单的excel导出,可以用easy-excel, fast-excel, auto-poi,在导出实体类上加上对应的注解,用封装好的工具类直接导出,但对于复杂的场景, 封装的工具类解决不了,要用原生的excel导出(easy-excel, fast-excel, auto-poi都支持原生的) 业务场景: 根据…...
创新实训项目初始化——gitee的使用
创新实训项目管理采用gitee,写下这篇博客熟悉gitee进行项目创建和版本同步 一、gitee概述 Gitee 是一个基于 Git 的代码托管平台,与 GitHub 类似,Gitee 提供了丰富的功能,比如代码仓库的创建、分支管理、代码审查等。 二、gite…...
【原创】使用ElasticSearch存储向量实现大模型RAG
一、概述 检索增强生成(Retrieval-Augmented Generation,RAG)已成为大型语言模型(LLM)应用的重要架构,通过结合外部知识库来增强模型的回答能力,特别是在处理专业领域知识、最新信息或企业私有数…...
Gymnasium Cart Pole 环境与 REINFORCE 算法 —— 强化学习入门 2
Title: Gymnasium Cart Pole 环境与 REINFORCE 算法 —— 强化学习入门 2 文章目录 I. Gymnasium Cart Pole 环境II. REINFORCE 算法1. 原理说明2. REINFORCE 算法实现 I. Gymnasium Cart Pole 环境 Gymnasium Cart Pole 环境是一个倒立摆的动力学仿真环境. 状态空间: 0: Ca…...
响应式数据 和 Pinia 状态
响应式数据 和 Pinia 状态 是 Vue.js 应用中用于管理数据的两种重要机制,它们之间有密切的关系。以下是它们的定义、特点以及关系: 1. 响应式数据 定义 响应式数据 是 Vue.js 的核心特性之一,指的是当数据发生变化时,视图会自动…...
在大数据开发中hive是指什么?
hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在大数据技术的浩瀚星空中,Apache Hive犹如一座桥梁,连接着传统数据仓库理念…...
LeRobot源码剖析——对机器人各个动作策略的统一封装:包含ALOHA ACT、Diffusion Policy、VLA模型π0
前言 过去2年多的深入超过此前7年,全靠夜以继日的勤奋,一天当两天用,抠论文 抠代码 和大模型及具身同事讨论,是目前日常 而具身库里,idp3、π0、lerobot值得反复研究,故,近期我一直在抠π0及l…...
Python生成requirements.txt的两种方法
Python生成requirements.txt的两种方法 方法一:导出当前环境的依赖包 使用pipreqs --encodingutf8为使用utf8编码,避免编码报错 --force 强制执行覆盖生成目录下的requirements.txt # 安装 python3 -m pip install pipreqs # 在当前目录生成 pipreqs . …...
如何判断 MSF 的 Payload 是 Staged 还是 Stageless(含 Meterpreter 与普通 Shell 对比)
在渗透测试领域,Metasploit Framework(MSF)的 msfvenom 工具是生成 Payload(载荷)的核心利器。然而,当我们选择 Payload 时,经常会遇到一个问题:这个 Payload 是 Staged(…...
HTML5与CSS3新特性详解
一、HTML5新特性 1.概述 HTML5 的新增特性主要是针对于以前的不足,增加了一些新的标签、新的表单和新的表单属性等。 这些新特性都有兼容性问题,基本是 IE9 以上版本的浏览器才支持,如果不考虑兼容性问题,可以大量使用这些新特…...
Redis常用进阶 存储原理和主从思路
Redis常用进阶 存储原理和主从思路 简介 此篇用于需要时随时查阅的知识. 由于不断的学习总是会忘记一些 所以用于记录 笔记对应视频为黑马redis https://www.bilibili.com/video/BV1Pu411Y7bq 单点redis的问题 : 数据丢失问题 持久化并发能力弱 主从集群存储能力问题 ES故…...
本地部署DeepSeek-R1(Dify升级最新版本、新增插件功能、过滤推理思考过程)
下载最新版本Dify Dify1.0版本之前不支持插件功能,先升级DIfy 下载最新版本,目前1.0.1 Git地址:https://github.com/langgenius/dify/releases/tag/1.0.1 我这里下载到老版本同一个目录并解压 拷贝老数据 需先停用老版本Dify PS D:\D…...
分治-快速排序系列一>快速排序
目录 题目方法:优化方法:代码: 题目方法: 忘记快速排序看这里:链接: link 优化方法: 代码: public int[] sortArray(int[] nums) {qsort(nums,0,nums.length-1);return nums;}private void qso…...
【spring对bean Singleton和Prototype的管理流程】
在 Spring 框架中,Bean 的作用域决定了 Bean 的生命周期和创建方式。Spring 支持多种作用域,其中最常用的是 单例(Singleton) 和 原型(Prototype)。以下是 Spring 对单例和原型 Bean 的管理流程详解&#x…...
【Java】grpc-java在IDEA中build不成功的相关问题,Android,codegen C++语言排除
一、解决Android依赖问题 在当前grpc-java项目根目录下创建gradle.properties文件,输入以下内容: skipAndroid=true或者 android.useAndroidX=true二、com.google.cloud.tools.appengine插件找不到的问题 Plugin [id: ‘com.google.cloud.tools.appengine’, version: ‘…...
十七、实战开发 uni-app x 项目(仿京东)- 后端指南
前面我们已经用uniappx进行了前端实战学习 一、实战 开发uni-app x项目(仿京东)-规划-CSDN博客 二、实战 开发uni-app x项目(仿京东)-项目搭建-CSDN博客 三、实战开发 uni-app x 项目(仿京东)- 技术选型-CSDN博客 四、实战开发 uni-app x 项目(仿京东)- 页面设计-C…...