首页 文章 精选 留言 我的

精选列表

搜索[国产神器],共5622篇文章
优秀的个人博客,低调大师

GeoGebra 6.0.668.0 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。 GeoGebra 6.0.668.0版本现已发布,具体更新内容如下: Fixed:丢失的Labelling 菜单 Fixed:绘制抛物线等的问题 Fixed:在 iOS 上,输入框滚动小程序的问题 Fixed:IntersectPath(P, a) 与 Zip() Fixed:列表中 3D 角度的错误 Fixed:全屏按钮的错误 Technical change:使用Pointer Events Classic:修复"Keep Input"按钮为 null:= 的错误 确保 PgUp、PgDown 不改变图层 CAS:确保 Solve() 不会对不等式调用 NSolve() 详细信息

优秀的个人博客,低调大师

GeoGebra 6.0.659.0 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。 GeoGebra 6.0.659.0版本现已发布,具体更新内容如下: atan()、acos()、asin() 现在适用于复数 新参数 "detachKeyboard":true Classic 5:修复了输入框有焦点时对象消失的问题 Suite:增加了概率计算器子程序(仅限网页) 3D: 修复标示,例如立方体段等的问题 修复新的"Text as caption"标题的对齐方式 CAS:确保 Invert() 是准确的 详细信息

优秀的个人博客,低调大师

GeoGebra 6.0.652.0 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。 GeoGebra 6.0.652.0版本现已发布,具体更新内容如下: CAS:在 Keep Input 模式下修复例如 2/1E-12。 CAS:稍微简化了 Substitute() 的答案。 CAS:在考试模式中新增“save”选项(在安全区域)。 概率计算器:修复问题保存间隔。 详细信息

优秀的个人博客,低调大师

GeoGebra 6.0.639.0 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。 GeoGebra 6.0.639.0版本现已发布,具体更新内容如下: tracing functions的修复 从 pako.js 切换到 fflate.js 内置按钮图标切换为 SVG CAS:修复 Web 中的 Rationalize(1/(sqrt(3+ί)))(& smaller) CAS:对 acosd 和 atand 的修复 CAS:确保 Eigenvectors({{1,2},{3,4}}) 是精确的 详细信息

优秀的个人博客,低调大师

GeoGebra 6.0.596.0 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。 GeoGebra 6.0.596.0版本现已发布,具体更新内容如下: 修复下拉菜单无法在点击时关闭的问题 将 LaTeX 粘贴到 Algebra Input 和 Input Boxes 中的改进 用于有理函数的新命令 RemovableDiscontinuity()(也用于previews) Notes:新的表格工具 Editor:SVG export、添加了 evalLaTeX()和 event for <Enter>/focus lost Chrome:将图片复制到剪贴板中 详细信息

优秀的个人博客,低调大师

JIT的Profile神器JITWatch

简介 老是使用命令行工具在现代化社会好像已经跟不上节奏了,尤其是在做JIT分析时,使用LogCompilation输出的日志实在是太大了,让人望而生畏。有没有什么更加简便的方法来分析JIT日志呢?快来和小师妹一起来学习JITWatch吧。 什么是JIT 小师妹,F师兄,JIT就是Just In Time compilers。能不能再总结一下JIT到底是做什么的呢? 当然没问题,JIT主要有两个作用,第一个作用大家应该已经知道了,就是在运行时将byte code编译成为机器码,提高程序的执行速度。 第二个作用就是在运行时对代码进行优化,同样的也对性能进行提升。 JIT中有两种编译器,C1代表的是Client Compiler,C2代表的是Server Compiler。 其中C1只是简单的编译,而C2在收集到更多信息之后,会进行更加深入的编译和优化。 常见的优化手段有:Loop unrolling, Inlining, Dead Code Elimination,Escape analysis, Intrinsics, Branch prediction等。 JDK8中会默认启动分层编译。你也可以使用-XX:+TieredCompilation来手动启动它。 JITWatch简介 小师妹:F师兄,上次你讲的LogCompilation和PrintCompilation输出结果还是太复杂了,尤其是LogCompilation,输出的结果有十几M,分析起来好难。有没有更简单一点的办法,让我的工作效率加倍呢? 这个必须有,有需求就有市场,有需求就有大神出场。今天给你介绍一个工具叫做JITWatch。 JITWatch是一个大神做的JIT日志的可视化分析工具。在使用它之前你可能觉得它有点强大,在使用后你就会觉得它真的是强大。 运行JITWatch 小师妹:F师兄,这么强大的工具,快快介绍我使用吧。 完全没有问题,不过JITWatch没有现成的打包好的可执行文件。没错,你需要到github上面下载源码。 下载完毕,可以执行: mvn clean compile test exec:java 就可以开启JITWatch之旅了。 JITWatch详解 小师妹:F师兄,这么好用的工具为什么不打个包出来让大家直接用呢?还要下载源码这么麻烦。 其实吧,JITWatch为了大家方便使用,自带一个Sandbox功能,提供了一些可以直接在JITWatch中运行的代码,同时JITWatch可以实现源码的实时比对功能。所以需要大家下载源码。 闲话休提,我们开启JITWatch之旅吧。 入眼就是如此朴实无华的界面,让人感觉总有点...重剑无锋,大巧不工。高手做的UI就是这么的完美。 接下来我们需要运行一个程序,来实时感受一下JITWatch的魅力。 看到左边最上角的sandbox了吗?点开它可以看到下面的sandbox页面: 这一个页面会选择一个sadbox中的例子展示给你,大家注意下面的输出框的说明,它会显示你的Disassembler是否可用。如果想要安装disassembler,请参照我之前的文章。 如果你对这个例子不满意,或者你想使用自己的代码,那也完全没有问题。点击config。 这里你可以配置源代码的路径,可以选择VM的语言,还有各种VM的选项,下面的选项相信我在之前的文章中都已经介绍过了吧。 如果还有不懂的小伙伴,微信我,私聊我,1对1现场教学。 万事俱备,只欠东风,开始吧,我可是要成为Java王的男人! 然后我们就进入了TirView界面,这里我们可看到主界面分成了三部分,源代码,ByteCode和Assembly。 小师妹:真是热泪盈眶啊,终于不需要自己去添加那些XX参数了。面向界面编程,真好。 上面还有几个按钮,这里简单介绍一下他们的功能,具体的界面这里就不截图了,因为实在是太多了.... Chain会展示调用链。 Journal就是之前使用LogCompilation产生的xml日志。 LNT,全称是line number table。---目前我还不知道这个是做什么用的,有知道的朋友,请给我留言。 然后就是Inlined into功能了,这个功能要详细讲一下,因为会影响到程序的执行效率。 还记得之前举的inline的例子吗? int a = 1; int b = 2; int result = add(a, b); ... public int add(int x, int y) { return x + y; } int result = a + b; //内联替换 上面的add方法可以简单的被替换成为内联表达式。 JITWatch可以显示方法是否被inlined,并且显示出inlined的原因。 点击BCI可以显示关联的inlined的代码。大家自行体会。 现在再让我们回到可爱又有风格的主页面: 左边是源代码,包含了JDK自己的代码,如果你想详细的分析JDK自己代码的优化,那么这是一个非常好的工具。 右边显示的是被JIT编译的类和方法,并且展示了编译级别和编译的时间。 右上角又有一排按钮,Config是用来配置运行的代码。 TimeLine是以图形的形式展示JIT编译的时间轴。 Histo是直方图展示的一些编译信息。 TopList里面是编译中产生的一些对象的或者数据的排序。 Cache是free code cache空间。 NMethod是native方法。 Threads是JIT编译的线程。 TriView就是我们最开始展示的面板。 最后我们重点讲一下Suggestion: Suggestion是对代码的一些优化建议。 从上图我们可以看到在调用String的hashMap方法时候无法inlined,因为被调用的方法太大了,超出了最大inlining size。 总结 所以,我们通过JITWatch可以学到什么呢?最最重要的是我们可以通过JITWatch来分析JIT的运行原理和本质。然后inlined的方法不要太大了,否则影响执行效率。 本文作者:flydean程序那些事 本文链接:http://www.flydean.com/jvm-jit-jitwatch/ 本文来源:flydean的博客 欢迎关注我的公众号:程序那些事,更多精彩等着您!

优秀的个人博客,低调大师

GeoGebra 6.0.591.0 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。 GeoGebra 6.0.591.0版本现已发布,具体更新内容如下: log(x)现在给出log_10(x)而不是ln(x) 新命令 RemovableDiscontinuity() 用于有理函数(也用于预览) 修复 eg sin(x)^cos(x) 添加额外的参数到 ggbApplet.getValueString,以确保输出未本地化 修复增量为1°的sliders 详细信息

优秀的个人博客,低调大师

GeoGebra 6.0.587.0 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。 GeoGebra 6.0.587.0版本现已发布,具体更新内容如下: 无需显式乘法即可更好地解析表达式,例如 f(p,q)=sin(pq) 修复输入框有时在<Tab>上消失的问题 设置按钮边框颜色的新参数,例如"buttonBorderColor":"#ff00ff" Graphing:Length(list) working again Graphing:再次显示 Line(A, B)的方程式 符号输入框可用于圆锥曲线,隐式曲线和二次曲面 现在使用 GWT 2.9 构建 详细信息

优秀的个人博客,低调大师

GeoGebra 6.0.577.0 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。 GeoGebra 6.0.577.0版本现已发布,具体更新内容如下: Classic:修复了出现在 iOS 13.3.1 上的本机键盘 CAS App:sliders和vectors 正常工作 Classic:修复了 eg ggbApplet.evalCommand("$1:f(x)≔x^2") 确保InputBox1+"" and FormulaText(InputBox1)正常工作 修复符号输入框的 undo/redo 详细信息

优秀的个人博客,低调大师

GeoGebra 6.0.560 发布,绘图神器

Geogebra 是动态数学软件,它将几何、代数、电子表格、绘图、统计和微积分集成在一个易于使用的软件包中。GeoGebra 6.0.560内容如下: 输入框为空,而不是显示未定义的链接 geo的 '?' 输入框的选项对齐 Cas Calculator:添加了更多命令 Invert()、NSolutions()、Sequence()、ReducedRowEraconForm()、subpee()、sum()、transpose()、RemoveUnDefined()、Tangent() 发布说明

优秀的个人博客,低调大师

Sealos 就是小团队的神器

作者:阳明。Kubernetes 布道师,公众号 K8s 技术圈主理人 最近我们新开发了一个项目 fastclass.cn,这个项目是一个独立开发者的学习网站,我们的目标是帮助你使用 Figma、Python、Golang、React、VUE、Flutter、ChatGPT 等设计构建真实的应用程序,助你成为一个全栈开发者,算是在 youdianzhishi.com 的基础上的一个延伸。 由于该项目还处于早期阶段,所以我们需要尽可能地提高效率,减少重复劳动,这样才能更快地推出新的课程。该项目使用的技术栈如下: 前端:React、Next.js、Tailwind CSS 后端:Python、Django、MySQL、Celery、Redis 因为之前的项目是直接用 Docker 方式部署到阿里云的服务器上面的,为了节约成本,自然我们还是使用 Docker 容器的方式部署这个项目,但是由于该项目涉及到更多的服务,比如 Next.js、Celery 这些都比较消耗资源,导致我们的服务器性能不够,所以需要另外一种低成本的方式来部署,最好还能应对不断增长的流量。 Sealos 简介 在这种情况下,我就想到了 Kubernetes,因为 Kubernetes 可以很好地解决这个问题,但是如果我自己搭建 Kubernetes 集群的话,成本又会比较高,使用云服务商的 Kubernetes 服务,比如阿里云的 ACK、腾讯云的 TKE 等,成本也不会太低。这个时候想到了 Sealos 的云服务,其官网介绍:Sealos 是一个无需云计算专业知识,就能在几秒钟内部署、管理和扩展应用的云操作系统。就像使用个人电脑一样! 当然最终选择直接使用 Sealos 云服务主要还是因为其高效、经济:仅需为容器付费,自动伸缩杜绝资源浪费,大幅度节省成本。 这确实是非常符合我们的需求的,我完全不需要一个完整的 Kubernetes 集群,说白了就是我只需要跑几个 Pod 就行,不需要去维护整个集群,这样就能大大减少成本(经济成本、运维成本等),而且 Sealos 云服务还提供了很多功能,比如自动伸缩、监控、日志等,这些都是我需要的,有这样的服务,我就可以专注于开发,而不用去管运维了,何乐而不为呢? Sealos 是一个基于 Kubernetes 的云服务,所以要使用 Sealos 云服务,建议你最好了解一下 Kubernetes 的基本概念,比如 Pod、Service、Deployment、Ingress 等,这样会更容易上手,当然不了解也不影响你使用,因为 Sealos 云服务提供了很好的界面,你可以很容易地完成部署、管理、扩展等操作。 容器化 当然首先需要将我们的服务容器化,打包成 Docker 镜像,我们的后端服务代码结构如下所示: 容器化说白了就是将我们的服务打包成 Docker 镜像,我们的后端服务是一个 Django 项目,对应的 Dockerfile 内容如下所示: FROM python:3.11.4-slim-buster LABEL author=icnych@gmail.com # set environment variables ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 ENV DEBUG False WORKDIR /app RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && \ apt-get update && \ apt-get install -y pkg-config python3-dev default-libmysqlclient-dev build-essential RUN pip install --upgrade pip --index-url https://mirrors.sustech.edu.cn/pypi/simple && \ pip config set global.index-url https://mirrors.sustech.edu.cn/pypi/simple COPY . . RUN pip install -r requirements.txt RUN apt-get clean autoclean && \ apt-get autoremove --yes && \ rm -rf /var/lib/{apt,dpkg,cache,log}/ \ EXPOSE 8000 CMD ["gunicorn", "--bind", ":8000", "--workers", "4", "--access-logfile", "-", "--error-logfile", "-", "fastclass.wsgi:application"] 这个 Dockerfile 文件很简单,就是基于 python:3.11.4-slim-buster 镜像构建,然后安装一些依赖,最后运行 gunicorn 启动 Django 项目。 另外需要注意我们这里使用了 Celery 来处理异步任务,使用的 Redis 做为 Broker,所以需要在 Django 的配置文件中配置 Celery,内容如下所示: # ==========Celery=========== REDIS_URL = os.getenv("REDIS_URL", "localhost:6379") REDIS_USER = os.getenv("REDIS_USER", "default") REDIS_PASSWORD = os.getenv("REDIS_PASSWORD", "default") REDIS_BROKER_DB = 1 REDIS_RESULT_DB = 2 CELERY_BROKER_URL = ( f"redis://{REDIS_USER}:{REDIS_PASSWORD}@{REDIS_URL}/{REDIS_BROKER_DB}" ) #: Only add pickle to this list if your broker is secured #: from unwanted access (see userguide/security.html) CELERY_ACCEPT_CONTENT = ["json"] CELERY_RESULT_BACKEND = ( f"redis://{REDIS_USER}:{REDIS_PASSWORD}@{REDIS_URL}/{REDIS_RESULT_DB}" ) CELERY_TASK_SERIALIZER = "json" CELERY_TIMEZONE = "Asia/Shanghai" CELERY_ENABLE_UTC = True 这里我们使用了环境变量来配置 Redis 的连接信息,这样就可以在容器启动的时候通过环境变量来配置。当然还有数据库的连接信息也是通过环境变量配置的,这样就可以很方便地在不同环境中配置不同的连接信息。 DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": os.getenv("DB_NAME", "fastclass"), "USER": os.getenv("DB_USER", "root"), "PASSWORD": os.getenv("DB_PASSWORD", "root"), "HOST": os.getenv("DB_HOST", "localhost"), "PORT": os.getenv("DB_PORT", 3306), "OPTIONS": {"charset": "utf8mb4"}, } } 接下来就是前端的 Next.js 项目,对应的项目结构如下所示: 同样需要将我们的 Next.js 项目容器化,对应的 Dockerfile 内容如下所示: FROM node:18.19.0-alpine3.18 AS base # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. RUN apk add --no-cache libc6-compat # 2. Rebuild the source code only when needed FROM base AS builder WORKDIR /app COPY . . # 切换镜像源 RUN npm config set registry https://repo.nju.edu.cn/repository/npm/ && npm install sharp && npm install --production && npm run build FROM base AS runner WORKDIR /app/web ENV NODE_ENV production # Uncomment the following line in case you want to disable telemetry during runtime. ENV NEXT_TELEMETRY_DISABLED 1 # copy need files(this can exclude code files) COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/.next ./.next COPY --from=builder /app/public ./public COPY --from=builder /app/docker/pm2.json ./pm2.json COPY --from=builder /app/docker/entrypoint.sh /entrypoint.sh COPY --from=builder /app/next.config.js ./next.config.js RUN npm install pm2 -g && chmod +x /entrypoint.sh EXPOSE 3000 ENTRYPOINT ["/bin/sh", "/entrypoint.sh"] 这里我们采用的是一个多阶段构建的方式,首先是基于 node:18.19.0-alpine3.18 镜像构建,然后安装依赖,最后使用 pm2 来启动 Next.js 项目。pm2 是一个 Node.js 进程管理工具,可以很方便地管理 Node.js 进程,比如启动、停止、重启等。这里我们通过 ENTRYPOINT 定义了一个脚本 entrypoint.sh,内容如下所示: #!/bin/bash set -e #if [[ -z "$APP_URL" ]]; then # export NEXT_PUBLIC_PUBLIC_API_PREFIX=${APP_API_URL}/api #else # export NEXT_PUBLIC_PUBLIC_API_PREFIX=${APP_URL}/api #fi # #export NEXT_PUBLIC_SENTRY_DSN=${SENTRY_DSN} /usr/local/bin/pm2 -v /usr/local/bin/pm2-runtime --raw start /app/web/pm2.json 这个脚本主要是启动 pm2,对应的 pm2.json 文件内容如下所示: { "apps": [ { "name": "FastClass", "exec_mode": "cluster", "instances": 2, "script": "./node_modules/next/dist/bin/next", "cwd": "/app/web", "args": "start" } ] } 最后分别前后端服务构建成 Docker 镜像,然后推送到镜像仓库,这样我们的服务就容器化完成了。 部署 现在有了应用镜像,接下来只需要将这些镜像部署到 Sealos 云服务上面就行了。 首先当然需要注册一个账号,前往 cloud.sealos.run 注册即可,国内用户需要实名认证,初始会提供 5 元的试用金,可以用来体验一下,整个控制台界面如下所示: 然后我们可以根据自己的业务需求选择不同的可用区域,我们这里选择的是北京 A区域。 由于我们的后端应用依赖 MySQL 和 Redis 数据库,所以我们首先要创建这两个数据库,Sealos 也是提供了单独的数据库服务的(底层使用的是 kubeblocks),选择新建数据库,然后选择要创建的数据库类型,我们先选择 MySQL 数据库。 然后我们可以配置数据库的名称、CPU、内存资源,我们可以选择最低配置,如果后面发现资源不够,可以随时变更资源,这里我们配置的 CPU 和内存实际上就是 Pod 里面的 limit 资源,另外就是实例数建议最低配置为 3 个,这样可以保证数据库的高可用性,在左侧也有对应的资源预估价格显示。我们也可以切换查看对应的 YAML 资源清单文件: 其实这就是 KubeBlocks 的一个 CR 实例。配置完成后点击右上角的"部署"按钮,等待部署完成即可。用同样的方式再部署一个 Redis 数据库即可。 点击查看详情,在左侧可以看到数据库的连接信息,我们的后端服务需要用到这些信息。在右侧可以看到数据库的实时监控信息,我们可以根据这些信息来调整数据库的资源配置,此外还可以备份数据库,在线导入数据等。 数据库准备好过后,接下来就可以部署我们的应用了,点击首页的"应用管理",开始新建应用。首先我们来部署后端服务,在表单中填上后端服务的镜像相关信息。然后部署模式有固定实例和弹性伸缩两种模式,弹性伸缩也就是我们熟悉的 HPA 模式,比如我们这里配置的是内存使用率超过 80% 时,自动扩容到 2 个 Pod,同样还可以配置 CPU、内存等资源。 如果想要对外暴露后端服务,可以在网络配置中开启公网访问,也就是创建一个 Ingress 资源,这样就可以通过公网访问我们的后端服务了,我们这里暂时不需要,所以不勾选。 另外还需要在高级配置里面配置环境变量,比如数据库连接信息、Redis 连接信息等,这样我们的后端服务就可以连接到数据库和 Redis 了。 我们只需要简单的在页面上填写一些配置信息,其实就对应着 Kubernetes 里面的一些资源,比如 Deployment、Service、Ingress、HPA、Secret 等,Sealos 云服务会根据我们的配置信息生成对应的资源清单文件,然后部署到 Kubernetes 集群上面。 配置完成后点击右上角的"部署"按钮,等待部署完成即可,部署完成后我们可以在应用列表中看到我们的后端服务已经部署成功了。 用同样的方式部署前端服务,这里需要注意的是需要开启公网访问,因为我们的前端服务是需要对外暴露的,这样用户才能访问到我们的网站。 而且需要注意开启公网访问后,系统会自动为我们分配一个域名,我们肯定是希望使用自己的域名,所以需要自定义域名,需要在域名服务商处添加自定义域名的 CNAME 解析到这个自动生成的域名地址。 这样我们的前端服务就可以通过自定义域名访问了,但是这里还有一个问题,就是我们的前端 Next.js 服务还需要访问我们的后端服务,当我们访问 https://fastclass.cn 的时候会访问到前端服务,但是当访问 https://fastclass.cn/api/xxx 的时候需要访问到后端服务,这个时候就需要配置 Ingress 路由规则,将 /api 路由转发到后端服务,但是 Sealos 云服务的页面上目前还不支持配置 Ingress 路由规则,所以我们需要手动配置 Ingress 路由规则。 点击"终端"就可以进入到 Kubernetes 集群的终端界面,然后我们可以通过 kubectl 来管理 Kubernetes 集群,首先需要将 fastclass.cn 的 https 证书导入到 Kubernetes 集群中,用一个 Secret 对象来存储证书信息,然后我们修改下系统自动生成的 Ingress 对象,将 https 证书换成我们自己的证书。 然后再创建一个新的 Ingress 对象,用来配置后端服务的路由规则,这样我们的前端服务就可以访问到后端服务了,如下所示: 这样我们就可以正常访问我们的网站了。除此之外我们还需要部署下 Celery 服务,用来处理后端的异步任务的。和部署后端服务类似,也是使用相同的镜像和环境变量,不过需要注意的是这里我们不是启动 Web 服务,而是启动 Celery Worker 服务,所以需要修改启动命令。 同样还有一个定时任务服务,用来定时执行一些任务,这里我们使用的是 Celery Beat 服务,同样需要使用相同的镜像和环境变量,不过需要修改启动命令,命令如下所示: celery -A fastclass beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler 最终我们部署了 4 个服务,分别是前端服务、后端服务、Celery Worker 服务、Celery Beat 服务,这样我们的应用就部署完成了。 后续其他的功能服务,我们也可以采用微服务的方式来部署,非常方便。 在 KubePanel 里面也可以看到我们整个集群的资源使用情况,相当于一个 Kubernetes 集群 Dashboard。 如果控制台页面不支持的一些 Kubernetes 功能特性,我们还可以通过终端来自行操作,就相当于我们平时使用的 Kubernetes 集群一样。 此外我们还可以将集群的 kubeconfig 文件导入到本地,这样我们就可以使用 kubectl 命令在本地来管理集群了。 在费用中心也可以看到我们的消费详细账单信息。 我们这里只是使用了 Sealos 的一部分功能,还有很多其他功能,比如对象存储、云开发等等能力,大家可以自行探索。 这不比买 ECS 服务器折腾来得简单方便吗?成本也降低不少,如果你是一个创业团队,需要小步快跑,快速验证产品,那么 Sealos 绝对是你应用托管的一个最佳选择。

优秀的个人博客,低调大师

DBA 抓包神器 tshark 测评

想窥探神秘的网络世界的奥秘,tshark 助你一臂之力! 作者:赵黎明 爱可生 MySQL DBA 团队成员,熟悉 Oracle、MySQL 等数据库,擅长数据库性能问题诊断、事务与锁问题的分析等,负责处理客户 MySQL 及我司自研 DMP 平台日常运维中的问题,对开源数据库相关技术非常感兴趣。 本文来源:原创投稿 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 常用抓包工具 tshark、tcpdump 和 Wireshark 都是网络抓包工具,它们可以在网络上捕获和分析数据包。 tcpdump 一个开源的,基于命令行的网络抓包工具。它可以捕获和分析网络数据包,运行在几乎所有的 Unix 和 Linux 系统上;可以抓取实时网络通信中的数据包,然后通过过滤器及其他参数,对数据包进行解析和处理。 tshark Wireshark 的命令行版本,也是一个开源的网络分析工具。它可以在命令行下捕获和分析网络流量数据,并使用 Wireshark 的过滤器来提取所需的数据,还支持与各种脚本语言(如 Python 和 Perl)结合使用,以自动化分析过程。 Wireshark 是一个流行的网络协议分析器,支持从在线网络或本地文件中捕获数据包,并提供了图形化用户界面来展示数据包内容;可以解析并显示各种网络协议,并提供了强大的分析工具以及过滤器;与 tshark 和 tcpdump 相比,Wireshark 的优势在于它提供了友好的 GUI 界面,使用户更轻松地进行网络协议的分析和调试。 小结 以上这些工具都可以直接捕获和分析网络数据包,但它们在使用方式和功能上略有不同;通常,我们会先用 tcpdump 或 tshark 在目标服务器上抓包生成 pcap 文件,再将其拿到装有 Wireshark 的主机上进行分析,本文将会分享 tshark 和 Wireshark 的一些使用技巧。 三次握手和四次挥手 TCP 协议中的三次握手和四次挥手是 TCP 连接建立和关闭的过程。 三次握手 客户端向服务器发送 SYN 报文(请求建立连接) 服务器收到 SYN 报文后,回复 SYN+ACK 报文(同意建立连接) 客户端收到 SYN+ACK 报文后,再回复 ACK 报文(确认连接建立) 四次挥手 客户端向服务器发送 FIN 报文(请求断开连接) 服务器收到 FIN 报文后,回复 ACK 报文(确认收到请求) 当服务器确认数据已经全部发送完毕后,它会向客户端发送 FIN 报文(关闭连接) 客户端收到 FIN 报文后,回复 ACK 报文(表示确认收到关闭请求),至此,整个 TCP 连接就被彻底关闭了 三次握手用于建立连接,是双方协商建立 TCP 连接的过程;四次挥手用于断开连接,是双方结束 TCP 连接的过程;不过,有时候四次挥手也会变成三次(如果没有数据发送,2 个包会合并传输)。 三次握手和四次挥手的过程 我们可以通过 tshark 抓包来观察 TCP 连接、断开的具体过程。 -- 在服务端执行 tshark 命令进行抓包 dmp2 (master) ~# tshark -f 'tcp port 3332 and host 10.186.61.83' Running as user "root" and group "root". This could be dangerous. Capturing on 'eth0' ==> 等待捕获 TCP 包直到有内容输出 # 此处省略了 -i,默认会选择第一个非 loopback 的网络接口(可简写为 lo),效果与指定 -i eth0 相同 # -f,指定捕获过滤器的表达式,可指定需要捕获的内容,如:协议、端口、主机IP等 -- 通过 MySQL 客户端远程连接到 MySQL 实例,等待片刻后再退出 {master} ~# m3332 -s(此处配置了 alias,可省略具体的连接串) mysql: [Warning] Using a password on the command line interface can be insecure. mysql> exit -- 观察屏幕输出 1、三次握手 从左到右的字段依次代表序号、时间戳(纳秒)、源端 IP、目标端 IP、协议、包的长度(字节)、具体信息(包括源/目标端口号或设备名、标志位等内容) 1 0.000000000 10.186.61.83 -> 10.186.60.68 TCP 74 38858 > mcs-mailsvr [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=2369606050 TSecr=0 WS=128 2 0.000018368 10.186.60.68 -> 10.186.61.83 TCP 74 mcs-mailsvr > 38858 [SYN, ACK] Seq=0 Ack=1 Win=28960 Len=0 MSS=1460 SACK_PERM=1 TSval=2369617045 TSecr=2369606050 WS=128 3 0.000233161 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=2369606050 TSecr=2369617045 4 0.000592420 10.186.60.68 -> 10.186.61.83 TCP 148 mcs-mailsvr > 38858 [PSH, ACK] Seq=1 Ack=1 Win=29056 Len=82 TSval=2369617045 TSecr=2369606050 5 0.000827920 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=1 Ack=83 Win=29312 Len=0 TSval=2369606051 TSecr=2369617045 6 0.000833512 10.186.61.83 -> 10.186.60.68 TCP 102 38858 > mcs-mailsvr [PSH, ACK] Seq=1 Ack=83 Win=29312 Len=36 TSval=2369606051 TSecr=2369617045 7 0.000837263 10.186.60.68 -> 10.186.61.83 TCP 66 mcs-mailsvr > 38858 [ACK] Seq=83 Ack=37 Win=29056 Len=0 TSval=2369617045 TSecr=2369606051 8 0.001997998 10.186.61.83 -> 10.186.60.68 TCP 264 38858 > mcs-mailsvr [PSH, ACK] Seq=37 Ack=83 Win=29312 Len=198 TSval=2369606052 TSecr=2369617045 9 0.002021916 10.186.60.68 -> 10.186.61.83 TCP 66 mcs-mailsvr > 38858 [ACK] Seq=83 Ack=235 Win=30080 Len=0 TSval=2369617047 TSecr=2369606052 10 0.006977223 10.186.60.68 -> 10.186.61.83 TCP 2088 mcs-mailsvr > 38858 [PSH, ACK] Seq=83 Ack=235 Win=30080 Len=2022 TSval=2369617052 TSecr=2369606052 11 0.007227340 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=235 Ack=2105 Win=33280 Len=0 TSval=2369606057 TSecr=2369617052 12 0.008426447 10.186.61.83 -> 10.186.60.68 TCP 171 38858 > mcs-mailsvr [PSH, ACK] Seq=235 Ack=2105 Win=33280 Len=105 TSval=2369606058 TSecr=2369617052 13 0.008812324 10.186.60.68 -> 10.186.61.83 TCP 308 mcs-mailsvr > 38858 [PSH, ACK] Seq=2105 Ack=340 Win=30080 Len=242 TSval=2369617053 TSecr=2369606058 14 0.009099712 10.186.61.83 -> 10.186.60.68 TCP 291 38858 > mcs-mailsvr [PSH, ACK] Seq=340 Ack=2347 Win=36224 Len=225 TSval=2369606059 TSecr=2369617053 15 0.009189644 10.186.60.68 -> 10.186.61.83 TCP 106 mcs-mailsvr > 38858 [PSH, ACK] Seq=2347 Ack=565 Win=31104 Len=40 TSval=2369617054 TSecr=2369606059 16 0.009443936 10.186.61.83 -> 10.186.60.68 TCP 132 38858 > mcs-mailsvr [PSH, ACK] Seq=565 Ack=2387 Win=36224 Len=66 TSval=2369606059 TSecr=2369617054 17 0.009656405 10.186.60.68 -> 10.186.61.83 TCP 187 mcs-mailsvr > 38858 [PSH, ACK] Seq=2387 Ack=631 Win=31104 Len=121 TSval=2369617054 TSecr=2369606059 18 0.049641532 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=631 Ack=2508 Win=36224 Len=0 TSval=2369606100 TSecr=2369617054 # 序号 1-3 的包,即 TCP 三次握手的过程 # 1)1 10.186.61.83 -> 10.186.60.68 TCP 74 38858 > mcs-mailsvr [SYN] Seq=0 # 2)2 10.186.60.68 -> 10.186.61.83 TCP 74 mcs-mailsvr > 38858 [SYN, ACK] Seq=0 Ack=1 # 3)3 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=1 Ack=1 2、四次挥手(在客户端执行 exit 命令后才会输出) 19 86.744173501 10.186.61.83 -> 10.186.60.68 TCP 100 38858 > mcs-mailsvr [PSH, ACK] Seq=631 Ack=2508 Win=36224 Len=34 TSval=2369692794 TSecr=2369617054 20 86.744194551 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [FIN, ACK] Seq=665 Ack=2508 Win=36224 Len=0 TSval=2369692794 TSecr=2369617054 21 86.744389417 10.186.60.68 -> 10.186.61.83 TCP 66 mcs-mailsvr > 38858 [FIN, ACK] Seq=2508 Ack=666 Win=31104 Len=0 TSval=2369703789 TSecr=2369692794 22 86.744632203 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=666 Ack=2509 Win=36224 Len=0 TSval=2369692795 TSecr=2369703789 # 序号 20-22 的包,为四次挥手的过程,这里由于服务器并没有数据要传输给客户端,所以将 FIN 和 ACK 合并在一个 TCP 包中了,即所谓的四次挥手变成了三次 # 1)20 19 86.744173501 10.186.61.83 -> 10.186.60.68 TCP 100 38858 > mcs-mailsvr [PSH, ACK] Seq=631 Ack=2508 # 2)21 10.186.60.68 -> 10.186.61.83 TCP 66 mcs-mailsvr > 38858 [FIN, ACK] Seq=2508 Ack=666 # 3)22 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=666 Ack=2509 TCP 包标志位的说明 TCP(传输控制协议)包头部有 6 个标志位(Flag),分别为 URG、ACK、PSH、RST、SYN、FIN,它们的十六进制值分别为:0x20、0x10、0x08、0x04、0x02、0x01,其中每个标志位的意义如下: URG 标志:紧急指针是否有效 ACK 标志:确认号是否有效 PSH 标志:Push操作,尽可能快地将数据交给应用层 RST 标志:重置连接 SYN 标志:发起一个新的连接 FIN 标志:释放连接 tshark常见用法示例 1. tshark 以自定义字段来展示信息 -- 服务端执行抓包 dmp2 (master) ~# tshark -i eth0 -d tcp.port==3332,mysql -f "host 10.186.61.83 and tcp port 3332" -T fields -e frame.time -e ip.host -e tcp.flags Running as user "root" and group "root". This could be dangerous. Capturing on 'eth0' # -T fields,可以指定需要输出的字段,需配合 -e 一起使用,此处将分别打印获取包的时间、主机 IP 及 TCP 的标志位,这些字段会按照 -e 的顺序进行排列展示 # -e,支持多种协议下的字段展示,具体用法查询路径:Wireshark -> 分析 -> 显示过滤器表达式 -- 通过 MySQL 客户端连接实例,执行一个查询,再退出(共有 3 部分:连接、通信、断连) {master} ~# m3332 -s mysql: [Warning] Using a password on the command line interface can be insecure. mysql> select @@version; @@version 5.7.36-log mysql> exit -- 观察屏幕输出 1、三次握手 "Jun 6, 2023 14:41:42.839863403 CST" 10.186.61.83,10.186.60.68 0x00000002 "Jun 6, 2023 14:41:42.839904347 CST" 10.186.60.68,10.186.61.83 0x00000012 "Jun 6, 2023 14:41:42.840263352 CST" 10.186.61.83,10.186.60.68 0x00000010 "Jun 6, 2023 14:41:42.840666158 CST" 10.186.60.68,10.186.61.83 0x00000018 "Jun 6, 2023 14:41:42.841604106 CST" 10.186.61.83,10.186.60.68 0x00000010 "Jun 6, 2023 14:41:42.841612112 CST" 10.186.61.83,10.186.60.68 0x00000018 "Jun 6, 2023 14:41:42.841616568 CST" 10.186.60.68,10.186.61.83 0x00000010 "Jun 6, 2023 14:41:42.842524996 CST" 10.186.61.83,10.186.60.68 0x00000018 "Jun 6, 2023 14:41:42.842550796 CST" 10.186.60.68,10.186.61.83 0x00000010 "Jun 6, 2023 14:41:42.848566815 CST" 10.186.60.68,10.186.61.83 0x00000018 "Jun 6, 2023 14:41:42.848826004 CST" 10.186.61.83,10.186.60.68 0x00000010 "Jun 6, 2023 14:41:42.850258537 CST" 10.186.61.83,10.186.60.68 0x00000018 "Jun 6, 2023 14:41:42.850881377 CST" 10.186.60.68,10.186.61.83 0x00000018 "Jun 6, 2023 14:41:42.851278991 CST" 10.186.61.83,10.186.60.68 0x00000018 "Jun 6, 2023 14:41:42.851395808 CST" 10.186.60.68,10.186.61.83 0x00000018 "Jun 6, 2023 14:41:42.851667278 CST" 10.186.61.83,10.186.60.68 0x00000018 "Jun 6, 2023 14:41:42.851926804 CST" 10.186.60.68,10.186.61.83 0x00000018 "Jun 6, 2023 14:41:42.892409030 CST" 10.186.61.83,10.186.60.68 0x00000010 # 前三个包分别为:0x02 [SYN] 、0x12 [SYN, ACK] 、0x10 [ACK],即三次握手的过程 # 后面的几个包:0x18 [PSH, ACK]、0x10 [ACK],是数据传输的过程 2、执行一个查询 "Jun 6, 2023 14:42:19.967273148 CST" 10.186.61.83,10.186.60.68 0x00000018 "Jun 6, 2023 14:42:19.967553321 CST" 10.186.60.68,10.186.61.83 0x00000018 "Jun 6, 2023 14:42:19.967835719 CST" 10.186.61.83,10.186.60.68 0x00000010 # 当 TCP 连接完成后,在数据传输过程中获取的包,其标志位为 0x18 [PSH, ACK] 或 0x10 [ACK] 3、四次挥手 "Jun 6, 2023 14:43:06.157240404 CST" 10.186.61.83,10.186.60.68 0x00000018 "Jun 6, 2023 14:43:06.157833986 CST" 10.186.61.83,10.186.60.68 0x00000011 "Jun 6, 2023 14:43:06.166359966 CST" 10.186.61.83,10.186.60.68 0x00000011 "Jun 6, 2023 14:43:06.166378115 CST" 10.186.60.68,10.186.61.83 0x00000010 "Jun 6, 2023 14:43:06.166971169 CST" 10.186.60.68,10.186.61.83 0x00000011 "Jun 6, 2023 14:43:06.167317550 CST" 10.186.61.83,10.186.60.68 0x00000010 # 看最后 4 个包,0x11 [FIN,ACK]、0x10 [ACK]、0x11 [FIN,ACK]、0x10 [ACK],这是标准的四次挥手过程 2. tshark 抓取 MySQL 中执行的 SQL -- 在服务器上执行抓包 dmp2 (master) ~# tshark -f 'tcp port 3332' -Y "mysql.query" -d tcp.port==3332,mysql -T fields -e frame.time -e ip.src -e ip.dst -e mysql.query Running as user "root" and group "root". This could be dangerous. Capturing on 'eth0' # -Y,指定显示过滤器表达式,在单次分析中可以代替 -R 选项,此处表示仅显示 mysql.query 相关的包 # -d,用于指定该抓包会话的协议详细解析器模块,可以执行 tshark -d help 来查看可用的协议(执行虽然会报错,但会显示所有支持的协议),此处表示将 3332 端口上的 TCP 包以 MySQL 协议进行解析 # -T fields -e mysql.query,即可获取符合 MySQL 协议的 SQL 语句 # -e ip.src -e ip.dst 的写法,也可以用 -e ip.host 来替换 -- 先停止从库复制后再启动 zlm@10.186.60.74 [(none)]> stop slave; Query OK, 0 rows affected (0.06 sec) zlm@10.186.60.74 [(none)]> start slave; Query OK, 0 rows affected (0.05 sec) -- 观察屏幕输出 "Jun 6, 2023 16:11:38.831359581 CST" 10.186.60.74 10.186.60.68 SELECT UNIX_TIMESTAMP() "Jun 6, 2023 16:11:38.832278722 CST" 10.186.60.74 10.186.60.68 SELECT @@GLOBAL.SERVER_ID "Jun 6, 2023 16:11:38.832613595 CST" 10.186.60.74 10.186.60.68 SET @master_heartbeat_period= 1000000000 "Jun 6, 2023 16:11:38.832861743 CST" 10.186.60.74 10.186.60.68 SET @master_binlog_checksum= @@global.binlog_checksum "Jun 6, 2023 16:11:38.833078690 CST" 10.186.60.74 10.186.60.68 SELECT @master_binlog_checksum "Jun 6, 2023 16:11:38.833278049 CST" 10.186.60.74 10.186.60.68 SELECT @@GLOBAL.GTID_MODE "Jun 6, 2023 16:11:38.833489342 CST" 10.186.60.74 10.186.60.68 SELECT @@GLOBAL.SERVER_UUID "Jun 6, 2023 16:11:38.833769721 CST" 10.186.60.74 10.186.60.68 SET @slave_uuid= '90161133-88b1-11ed-bbcc-02000aba3c4a' # 通过指定 MySQL 协议解析模块,此处捕获到了 MySQL 从实例在启动复制时会执行的 SQL 语句 # 如已用 -d 选项指定了协议、端口等信息时,可省略 -f(抓包过滤器表达式),除非还有其他的过滤需求,但不建议省略 -Y(显示过滤器表达式),否则会输出非常多的信息,以下两种写法是等效的: tshark -f 'tcp port 3332' -Y "mysql.query" -d tcp.port==3332,mysql -T fields -e frame.time -e ip.host -e mysql.query tshark -Y "mysql.query" -d tcp.port==3332,mysql -T fields -e frame.time -e ip.host -e mysql.query -- 获取类型为 Query 的 SQL dmp2 (master) ~# tshark -i lo -d tcp.port==3332,mysql -Y "mysql.command==3" -T fields -e ip.host -e mysql.query -e frame.time -c 10 Running as user "root" and group "root". This could be dangerous. Capturing on 'Loopback' 127.0.0.1,127.0.0.1 START TRANSACTION "Jun 7, 2023 17:17:29.194080437 CST" 127.0.0.1,127.0.0.1 insert ignore into universe.u_delay(source,real_timestamp,logic_timestamp) values ('ustats', now(), 0) "Jun 7, 2023 17:17:29.194306733 CST" 127.0.0.1,127.0.0.1 update universe.u_delay set real_timestamp=now(), logic_timestamp = logic_timestamp + 1 where source = 'ustats' "Jun 7, 2023 17:17:29.194647464 CST" 127.0.0.1,127.0.0.1 COMMIT "Jun 7, 2023 17:17:29.194953692 CST" 4 packets captured # mysql.command=3,表示执行的 SQL 类型为 Query,共支持 30 多种预设值 # 对于熟悉 DMP 的小伙伴,一看便知这是由平台纳管的一个实例,当前正在做时间戳的写入(判断主从延时的依据) -- 获取与 show 相关的 SQL dmp2 (master) ~# tshark -i lo -d tcp.port==3332,mysql -Y 'mysql.query contains "show"' -T fields -e ip.host -e mysql.query -e frame.time -c 10 Running as user "root" and group "root". This could be dangerous. Capturing on 'Loopback' 127.0.0.1,127.0.0.1 show slave status "Jun 7, 2023 17:37:44.672060318 CST" 127.0.0.1,127.0.0.1 show global status "Jun 7, 2023 17:37:44.672808866 CST" 127.0.0.1,127.0.0.1 show global variables "Jun 7, 2023 17:37:44.672845236 CST" 127.0.0.1,127.0.0.1 show global variables where Variable_name = 'innodb_flush_log_at_trx_commit' or Variable_name = 'sync_binlog' "Jun 7, 2023 17:37:44.673036197 CST" 4 packets captured dmp2 (master) ~# tshark -i lo -d tcp.port==3332,mysql -Y 'mysql.query matches "^show"' -T fields -e ip.host -e mysql.query -e frame.time -c 10 Running as user "root" and group "root". This could be dangerous. Capturing on 'Loopback' 127.0.0.1,127.0.0.1 show global status "Jun 7, 2023 17:56:02.671895630 CST" 127.0.0.1,127.0.0.1 show slave status "Jun 7, 2023 17:56:02.671944388 CST" 127.0.0.1,127.0.0.1 show global variables "Jun 7, 2023 17:56:02.671998965 CST" 127.0.0.1,127.0.0.1 show master status "Jun 7, 2023 17:56:02.672673795 CST" 4 packets captured # contains 使用字符串进行匹配,只要在数据包中存在指定的字符串,就会匹配成功,不论该字符串出现在查询的任何位置 # matches 支持使用正则表达式进行匹配,匹配符合指定规则的数据包,如:^show # 用 contains/maches 进行匹配查找时,关键词需用双引号包围,此时外层建议使用单引号,因为 maches 进行正则匹配时,外层使用双引号会报错,contains 则不限制 # 以上匹配方式类似模糊查询,但会区分大小写,如果指定 Show 或 SHOW 为关键词,可能获取不到 SQL 3. tshark 抓取 OB 中执行 SQL 与之前的方法类似,只需调整 IP 地址和端口号即可。 -- 抓取 5 个 mysql.query 协议的包 [root@10-186-65-73 ~]# tshark -i lo -Y "mysql.query" -d tcp.port==2881,mysql -T fields -e frame.time -e ip.host -e mysql.query -c 5 Running as user "root" and group "root". This could be dangerous. Capturing on 'Loopback' "Jun 7, 2023 15:40:12.886615893 CST" 127.0.0.1,127.0.0.1 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ __all_tenant.tenant_id, tenant_name, mem_used, access_count, hit_count from v$plan_cache_stat join __all_tenant on v$plan_cache_stat.tenant_id = __all_tenant.tenant_id "Jun 7, 2023 15:40:12.889500546 CST" 127.0.0.1,127.0.0.1 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ tenant_name, tenant_id, case when event_id = 10000 then 'INTERNAL' when event_id = 13000 then 'SYNC_RPC' when event_id = 14003 then 'ROW_LOCK_WAIT' when (event_id >= 10001 and event_id <= 11006) or (event_id >= 11008 and event_id <= 11011) then 'IO' when event like 'latch:%' then 'LATCH' else 'OTHER' END event_group, sum(total_waits) as total_waits, sum(time_waited_micro / 1000000) as time_waited from v$system_event join __all_tenant on v$system_event.con_id = __all_tenant.tenant_id where v$system_event.wait_class <> 'IDLE' and (con_id > 1000 or con_id = 1) group by tenant_name, event_group 2 packets captured # 执行抓包命令的服务器是 OBServer 集群内的一个节点,2881 是 OB 的对外服务的端口号 # -c,指定抓取 5 个包,实际上只抓到了 2 个符合过滤条件的包 # 从获取的 SQL 语句来看,猜测是由 ocp_monagent 监控组件发起的信息收集相关的 SQL -- 抓包时过滤包含 “__all_” 视图的 SQL [root@10-186-65-73 ~]# tshark -i lo -Y 'mysql.query contains "__all_"' -d tcp.port==2881,mysql -T fields -e frame.time -e ip.host -e mysql.query -c 5 Running as user "root" and group "root". This could be dangerous. Capturing on 'Loopback' "Jun 7, 2023 18:14:38.895171334 CST" 127.0.0.1,127.0.0.1 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ tenant_name, tenant_id, stat_id, value from v$sysstat, __all_tenant where stat_id IN (10000, 10001, 10002, 10003, 10004, 10005, 10006, 140002, 140003, 140005, 140006, 40030, 60019, 60020, 60024, 80040, 80041, 130000, 130001, 130002, 130004, 20000, 20001, 20002, 30000, 30001, 30002, 30005, 30006, 30007, 30008, 30009, 30010, 30011, 30012, 30013, 40000, 40001, 40002, 40003, 40004, 40005, 40006, 40007, 40008, 40009, 40010, 40011, 40012, 40018, 40019, 50000, 50001, 50002, 50004, 50005, 50008, 50009, 50010, 50011, 50037, 50038, 60000, 60001, 60002, 60003, 60004, 60005, 60019, 60020, 60021, 60022, 60023, 60024, 80057, 120000, 120001, 120009, 120008) and (con_id > 1000 or con_id = 1) and __all_tenant.tenant_id = v$sysstat.con_id and class < 1000 "Jun 7, 2023 18:14:38.896653822 CST" 127.0.0.1,127.0.0.1 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ tenant_id, tenant_name, sum(total_waits) as total_waits, sum(time_waited_micro) / 1000000 as time_waited from v$system_event join __all_tenant on v$system_event.con_id = __all_tenant.tenant_id where v$system_event.wait_class <> 'IDLE' group by tenant_name 2 packets captured [root@10-186-65-73 ~]# tshark -i lo -Y 'mysql.query contains "__all_"' -d tcp.port==2881,mysql -T fields -e frame.time -e ip.host -e mysql.query > /tmp/monit_ob.txt Running as user "root" and group "root". This could be dangerous. Capturing on 'Loopback' 124 ^C You have mail in /var/spool/mail/root [root@10-186-65-73 ~]# cat /tmp/monit_ob.txt |grep -i select|wc -l # 可用此方法来获取一些常用的 “__all_” 视图相关的监控 SQL # 将捕获的 SQL 重定向到文本文件,再用 awk 处理一下就能获取完整的 SQL [root@10-186-65-73 ~]# awk -F " " '{for (i=7;i<=NF;i++)printf("%s ", $i);print ""}' /tmp/monit_ob.txt|cat -n|head -5 1 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ zone, name, value, time_to_usec(now()) as current from __all_zone 2 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ __all_tenant.tenant_id, tenant_name, cache_name, cache_size from __all_virtual_kvcache_info, __all_tenant where __all_tenant.tenant_id = __all_virtual_kvcache_info.tenant_id and svr_ip = '10.186.65.73' and svr_port = 2882 3 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ case when cnt is null then 0 else cnt end as cnt, tenant_name, tenant_id from (select __all_tenant.tenant_name, __all_tenant.tenant_id, cnt from __all_tenant left join (select count(1) as cnt, tenant as tenant_name from __all_virtual_processlist where svr_ip = '10.186.65.73' and svr_port = 2882 group by tenant) t1 on __all_tenant.tenant_name = t1.tenant_name) t2 4 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ case when cnt is null then 0 else cnt end as cnt, tenant_name, tenant_id from (select __all_tenant.tenant_name, __all_tenant.tenant_id, cnt from __all_tenant left join (select count(`state`='ACTIVE' OR NULL) as cnt, tenant as tenant_name from __all_virtual_processlist where svr_ip = '10.186.65.73' and svr_port = 2882 group by tenant) t1 on __all_tenant.tenant_name = t1.tenant_name) t2 5 select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ __all_tenant.tenant_id, tenant_name, mem_used, access_count, hit_count from v$plan_cache_stat join __all_tenant on v$plan_cache_stat.tenant_id = __all_tenant.tenant_id 4. tshark 抓包后用 Wireshark 解析 tshark 也可以像 tcpdump 一样,先在服务器上抓包,再拿到 Wireshark 的图形窗口中做进一步分析。 -- 抓取 50 个包并生成 pcap 文件 dmp2 (master) ~# tshark -d tcp.port==3332,mysql -f 'tcp port 3332 and host 10.186.61.83' -c 50 -w /tmp/61_83.pcap Running as user "root" and group "root". This could be dangerous. Capturing on 'eth0' # 注意,-w 指定的文件无需提前创建,但抓包会话必须对该目录有写入权限,否则会报权限不足的错误。 以下截图为三次握手和四次挥手的过程。 同样地,也可以在 Wireshark 中将 mysql.query 字段展示出来:Wireshark -> 编辑 -> 首选项 -> 外观 -> 列 。 以下显示过滤器表达式中的内容表示:将包中 TCP 端口为 3332,源端 IP 地址为 10.186.60.74,协议类型为 MySQL 的内容过滤并展示,效果如图: 结语 tshark 作为 Wireshark 的命令行工具,与我们比较熟悉的 tcpdump 相比,有其不少优点: 1. 更多的过滤条件 具有比 tcpdump 更多的过滤条件,可以更加精确地过滤所需的数据包,tshark 支持 Wireshark 过滤器语法的全部特性,并提供了更高级的功能。 2. 更加灵活的输出格式 可以以不同的文件格式和标准输出打印输出捕获数据,而 tcpdump 的输出格式非常有限。 3. 更好的可读性和易用性 输出会更加易于阅读,因为它会对分组进行解析并显示其中包含的各种数据,比如协议、参数和错误信息等。这些信息对数据包分析非常有帮助。 4. 更加轻量级 相比于 tcpdump,占用的系统资源较少,并且不需要将所有数据存储在内存中,从而能够处理更大的数据流。 5. 更多的网络协议 支持更多的网络协议,包括 IPv6、IS-IS、IPX 等,而 tcpdump 支持的协议种类相对较少。 综上,在一些较为复杂的数据包分析和网络问题诊断场景中,更推荐使用 tshark,而对于只需快速捕捉网络流量的简单应用场景,tcpdump 可能会更适合一些。 关于 SQLE 爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。 SQLE 获取 类型 地址 版本库 https://github.com/actiontech/sqle 文档 https://actiontech.github.io/sqle-docs/ 发布信息 https://github.com/actiontech/sqle/releases 数据审核插件开发文档 https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/auditplugin_development.html

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册