关于debug:Java设计模式精讲-Debug方式内存分析内附文档源码

download:Java设计模式精讲 Debug形式+内存剖析内附文档源码解析 Golang 定时工作库 gron 设计和原理简略说,每一个位都代表了一个工夫维度,* 代表选集,所以,下面的语义是:在每天早上的4点05分触发工作。但 cron 毕竟只是一个操作系统级别的工具,如果定时工作失败了,或者压根没启动,cron 是没法提醒开发者这一点的。并且,cron 和 正则表达式都有一种魔力,不知道大家是否感同身受,这里引用共事的一句名言: 这世界上有些语言非常相似: shell脚本, es查问的那个dsl语言, 定时工作的crontab, 正则表达式. 他们相似就相似在每次要写的时候基本都得从新现学一遍。 刚巧,最近看到了 gron 这个开源我的项目,它是用 Golang 实现一个并发安全的定时工作库。实现非常简略精美,代码量也不多。明天咱们就来一起拆散源码看一下,怎么基于 Golang 的能力做进去一个【定时工作库】。 Gron provides a clear syntax for writing and deploying cron jobs. gron 是一个泰国小哥在 2016 年开源的作品,它的个性就在于非常简略和清晰的语义来定义【定时工作】,你不必再去记 cron 的语法。咱们来看下作为使用者怎么上手。首先,咱们还是一个 go get 安装依赖:$ go get github.com/roylee0704/gron复制代码假设咱们期望在【时机】到了当前,要做的工作是打印一个字符串,每一个小时执行一次,咱们就可能这样:package main import ( "fmt""time""github.com/roylee0704/gron") func main() { c := gron.New()c.AddFunc(gron.Every(1*time.Hour), func() { fmt.Println("runs every hour.")})c.Start()}复制代码非常简略,而且即便是在 c.Start 之后咱们依然可能增加新的定时工作进去。反对了很好的扩展性。定时参数留意到咱们调用 gron.New().AddFunc() 时传入了一个 gron.Every(1*time.Hour)。这里其实你可能传入任何一个 time.Duration,从而把调度间隔从 1 小时调整到 1 分钟以至 1 秒。除此之外,gron 还很贴心地封装了一个 xtime 包用来把常见的 time.Duration 封装起来,这里咱们开箱即用。import "github.com/roylee0704/gron/xtime" ...

August 18, 2022 · 2 min · jiezi

关于IDEA:IDEA中Debug调试的高级武功秘籍助你快速追踪BUG

前言:Java 中各种 IDE 的 Debug 性能,都是通过 Java 提供的 Java Platform Debugger Architecture (JPDA) 来实现的。借助 Debug 性能,能够很不便的调试程序,疾速的模仿 / 找到程序中的谬误。 Interllij Idea 的 Debug 性能上说尽管看起来和 Eclipse 差不多,然而在应用体验上,还是要比 Eclipse 好了不少。 Debug 中,最罕用的莫过于下一步,下一个断点(Breakpoint),查看运行中的值几个操作;然而除了这些 IDE 还提供了一些 “高级” 的性能,能够帮忙咱们更不便的进行调试; 上面就介绍几种高级的并且也很有用的调试技巧。 Java8 Streams Debug:Stream 作为 Java 8 的一大亮点,它和 java.io 包里的 InputStream 和 OutputStream 是齐全不同的概念。 Java 8 中的 Stream 是对汇合(Collection)对象性能的加强,它专一于对汇合对象进行各种十分便当、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。 IntStream.iterate(1, n -> n + 1) .skip(100) .limit(100) .filter(PrimeFinder::isPrime)//查看是否是素数 .forEach(System.out::println);下面这段代码,就是一个 streams 的常见用法,对汇合排序并转换取值;IDEA 也提供了剖析 streams 过程的性能:(留神:IDEA中装置了 Java Stream Debugger 插件才反对此性能) ...

April 2, 2021 · 3 min · jiezi

关于golang:在vscode中go编码发生的问题整理

引言应用VsCode进行Go程序开发,咱们必定会碰到一些问题,这些问题有些是IDE的配置问题,有些是下载包的版本不统一问题,本文次要针对在开发过程中碰到的问题做一个简略的回顾和整顿。 后期筹备,必看在进行问题纠错前,先确保本人正确下载了golang的官网工具集go-tool,如果不确定,就跟着我的步骤操作一遍,可能操作后,你的问题就解决了。 1、配置golang的源。 go env -w GOPROXY=https://goproxy.cn,direct 而后咱们进行golang工具的默认工具服务下载: 2、Windows平台按下Ctrl+Shift+P,Mac平台按Command+Shift+P,这个时候VS Code界面会弹出一个输入框 3、咱们在这个输入框中输出>go:install,上面会主动搜寻相干命令,咱们抉择Go:Install/Update Tools这个命令,按下图选中并会回车执行该命令 在弹出的窗口选中所有,并点击“确定”按钮,进行装置。 期待装置实现,因为国内网络的特殊性,所以肯定要谁知好go的代理源,不然总是下载失败。 执行这一步之后,重启Vscode,如果这个时候可能解决你的问题,那就不须要再往下看了。 具体问题解决方案如果以上步骤不能解决你的问题,那就能够对应本人的问题来进行操作设置了。 一、VSCode中F12无奈跳转通用设置点击左下角点击齿轮,抉择设置界面(也能够间接快捷键CTRL+, 点击用户-扩大-go。进行如下设置 1、DocsTool批改成godoc 2、Use Language Server 去掉勾选 3、重启VsCode go mod模式如果进行上述操作后还是不行,并且你是应用的go mod 模式,那还有一种比拟非凡的形式能够解决这个问题。 执行命令go mod vendor导入依赖,这一步会将依赖转移至该我的项目根目录下的 vendor(主动新建) 文件夹下 此时F12就能够进行代码跳转了。 二、代码主动带出性能生效这个问题个别都是因为 go mod模式的切换导致的。如果你的我的项目是应用的Gopath模式(如果有同学对Gopath和Gomod这俩种模式不理解的,能够看看我的文章如何对待go moudle并利用于工作),那么你须要设置 go env -w GO111MODULE=off 这时候主动带出性能就可能正确应用了 如果你应用的是go mod模式,设置 go env -w GO111MODULE=on 主动带出性能也能够恢复正常。 文章参考go module 根本应用 vscode go 未找到任何定义 对于我我的博客|文章首发 最初本文到此结束,心愿对你有帮忙 ???? 如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。 更多精彩技术文章汇总在我的 公众号【程序员工具集]】,继续更新,欢送关注订阅珍藏。

March 17, 2021 · 1 min · jiezi

关于debug:调试器的原理总结

调试器的原理介绍调试器不论对于软件开发还是逆向剖析,破绽开掘和利用来说都是一个至关重要的工具。明天学习了下调试器的实现,这里总结下调试器的实现原理。 一、根底概念波及到调试,就不能只理解计算机顶层的常识,还须要晓得与调试器的实现非亲非故的汇编指令和寄存器的概念。 1. 汇编指令首先是汇编指令,汇编指令精简的详情就是:机器指令的助记符。维基百科中的具体定义如下: 汇编语言(英语:assembly language)是任何一种用于电子计算机、微处理器、微控制器,或其余可编程器件的低级语言。在不同的设施中,汇编语言对应着不同的机器语言指令集。一种汇编语言专用于某种计算机系统构造,而不像许多高级语言,能够在不同零碎平台之间移植。 应用汇编语言编写的源代码,而后通过相应的汇编程序将它们转换成可执行的机器代码。这一过程被称为汇编过程。 汇编语言应用助记符(Mnemonics)来代替和示意特定低级机器语言的操作。特定的汇编指标指令集可能会包含特定的操作数。许多汇编程序能够辨认代表地址和常量的标签(Label)和符号(Symbols),这样就能够用字符来代表操作数而无需采取写死的形式。广泛地说,每一种特定的汇编语言和其特定的机器语言指令集是一一对应的。比拟喜爱 Gray Hat Python: Python Programming for Hackers and Reverser 中对机器指令和汇编指令的类比解释 : 汇编指令之于机器指令就如同域名零碎。汇编指令就像是网站域名,机器指令就像是通过域名解析后的IP地址。例如汇编中的罕用的中断指令int 3,会首先转化为0xCC能力被CPU执行。 2. 寄存器寄存器是CPU外部的微型缓存,其次要用于在CPU执行过程中存储所需的变量。 在Inter推出的32位元指令集架构下,寄存器的品种有很多,但与这里次要波及到的有:通用寄存器,程序状态与管制寄存器,调试寄存器,指令寄存器,每个寄存器均为32位。 通用寄存器包含:EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI。 EAX: 又称累加器, Accumulator Register。次要用于计算操作和存储函数执行结束后的返回值。EBX: 无非凡阐明,可用于附加存储。ECX: 计数寄存器, Count Registet。通常用于循环操作中的计数器。然而要留神,ECX用于计数时和咱们平时写程序时从小到大递增技术不同,ECX是从大到小递加计数,比方当ECX须要管制100次的循环时,应用100开始,递加到0完结。EDX: 数据寄存器, Data Register。次要用于对EAX计算操作的扩大,存储EAX进行的简单计算中的额定附加值。ESI: 源寄存器, Source Index Register。在循环对数据进行解决时存储输出数据流的地位和数据操作的源索引。EDI: 目标寄存器, Destination Register。指向数据处理的后果地址或者目标索引。EBP: 栈基址指针寄存器, Base Register。指向线程执行过程中以后函数栈空间的基址。ESP: 栈顶指针寄存器, Stack Register。指向线程执行过程中以后函数栈空间的栈顶地位。程序控制与状态寄存器:EFLAGS。 EFLAGS: 又称标记寄存器, Flag Register。一共有32位,每一个位元都具备非凡的标记含意。次要的和程序调试相干的标记为: --> ZF(Zero Flag): 零标记位,标记某一个操作后后果是否为0.--> CF(Carry Flag): 进位标记位,标记某一个操作过程中是否从高位借位。--> OF(Over Flag): 溢出标记位,标记某一个操作后后果是否超出目标寄存器的最大可存储值。指令寄存器:EIP。 ...

October 8, 2020 · 2 min · jiezi

关于debug:第16问创建一张表时MySQL-的统计表是如何变化的

本文关键字: 统计表,debug问题咱们晓得在 MySQL 中创立一张表时,一些统计表会发生变化,比方:mysql/innodb_index_stats,会多出几行对新表的形容。 那么会变更几张表?这些统计表是如何变动的? 试验本期咱们用 MySQL 提供的 DBUG 工具来钻研 MySQL 的 SQL 解决流程。 起手先造个实例这里得略微改一下实例的启动文件 start,将 CUSTOM_MYSQLD 改为 mysqld-debug:重启一下实例,加上 debug 参数:咱们来做一两个试验,阐明 DBUG 包的作用:先设置一个简略的调试规定,咱们设置了两个调试选项: d:开启各个调试点的输入O,/tmp/mysqld.trace:将调试后果输入到指定文件而后咱们创立了一张表,来看一下调试的输入后果:能够看到 create table 的过程中,MySQL 的一些细节操作,比方分配内存 alloc_root 等 这样看还不够直观,咱们减少一些信息:来看看成果:能够看到输入变成了调用树的模式,当初就能够分辨出 alloc_root 调配的内存,是为了解析 SQL 时用的(mysql_parse) 咱们再减少一些有用的信息:能够看到后果中减少了文件名和行号:当初咱们能够在输入中找一下统计表相干的信息:能够看到 MySQL 在这里十分机智,间接执行了一个内置的存储过程来更新统计表。 沿着 que_eval_sql,能够找到其余相似的统计表,比方上面这些: 本次试验中,咱们借助了 MySQL 的 DBUG 包,来让 MySQL 将处理过程裸露进去。MySQL 中相似的技术还有不少,比方 performance_schema,OPTIMIZER_TRACE 等等。 这些技术将 MySQL 的不同方向的信息裸露进去,不便大家了解其中机制。对于 MySQL 的技术内容,你们还有什么想晓得的吗?连忙留言通知小编吧!

July 22, 2020 · 1 min · jiezi

用-GODEBUG-看调度跟踪

让 Go 更强大的原因之一莫过于它的 GODEBUG 工具,GODEBUG 的设置可以让 Go 程序在运行时输出调试信息,可以根据你的要求很直观的看到你想要的调度器或垃圾回收等详细信息,并且还不需要加装其它的插件,非常方便,今天我们将先讲解 GODEBUG 的调度器相关内容,希望对你有所帮助。 不过在开始前,没接触过的小伙伴得先补补如下前置知识,便于更好的了解调试器输出的信息内容。 原文地址:用 GODEBUG 看调度跟踪 前置知识Go scheduler 的主要功能是针对在处理器上运行的 OS 线程分发可运行的 Goroutine,而我们一提到调度器,就离不开三个经常被提到的缩写,分别是: G:Goroutine,实际上我们每次调用 go func 就是生成了一个 G。P:处理器,一般为处理器的核数,可以通过 GOMAXPROCS 进行修改。M:OS 线程这三者交互实际来源于 Go 的 M: N 调度模型,也就是 M 必须与 P 进行绑定,然后不断地在 M 上循环寻找可运行的 G 来执行相应的任务,如果想具体了解可以详细阅读 《Go Runtime Scheduler》,我们抽其中的工作流程图进行简单分析,如下: 当我们执行 go func() 时,实际上就是创建一个全新的 Goroutine,我们称它为 G。新创建的 G 会被放入 P 的本地队列(Local Queue)或全局队列(Global Queue)中,准备下一步的动作。唤醒或创建 M 以便执行 G。不断地进行事件循环寻找在可用状态下的 G 进行执行任务清除后,重新进入事件循环而在描述中有提到全局和本地这两类队列,其实在功能上来讲都是用于存放正在等待运行的 G,但是不同点在于,本地队列有数量限制,不允许超过 256 个。并且在新建 G 时,会优先选择 P 的本地队列,如果本地队列满了,则将 P 的本地队列的一半的 G 移动到全局队列,这其实可以理解为调度资源的共享和再平衡。 ...

August 19, 2019 · 4 min · jiezi

Node-项目调试

前言 作为一个程序员,感觉我们其实打代码的时间不多,大部分时间都在在调试上,所以如何调高我们调试的效率,这就成了我们的一个大问题了,经过在网上的搜索与自己的探索,就推荐这两种好用的调试方法吧 1 Chrome 调试因为 V8 检查器集成允许使用 Chrome 调试协议将 Chrome DevTools 附加到 Node.js 实例以进行调试。所以我们可以直接用 Chrome 进行调试。这个就最简单的的方法,直接在运行代码的地方加个前缀 --inspect,如下: node --inspect /bin/www这个时候我们在控制台会看到多出这么几个提示 Debugger listening on ws://127.0.0.1:9229/f54d4cb8-56bc-46c4-9b8e-fd7f2163c73cFor help, see: https://nodejs.org/en/docs/inspectorDebugger attached.看到这个我们打开 Chrome,f12 打开控制台,点击上面的 Node 图标 我们就可以打开一个新的调试 Node 的浏览器窗口,我们在代码中打的 debugger 和 console.log 都会在那个窗口显示和输出出来。 2 VS Code 大法在 vscode 中调试步骤也是比较简单,1、 点击蜘蛛图标,打开调试控制台 2、选择一下调试环境 这里我们就直接选 Node的了的啦 3、配置调试模式我们选择好环境之后,他会弹出一个 launch.json 的配置文件,这里面我们可以vscode 有很多调试模式,我们可以通过 add configurations 添加调试模式。等到我们要调试的时候就在 debug 菜单那边选模式,然后点击绿色三角开始调试。下面我们着重介绍一下几个常见的模式吧 3 VS Code Node 调试模式3.1 attach 模式这个先拉出来说,因为后面几个模式都是通过 VS Code 启动项目的,而这个模式是你项目已经启动的情况下启用的,并且那项目还是开启了 Chrome 调试的 ...

July 7, 2019 · 1 min · jiezi

实用Javascript调试技巧分享

见过太多同学调试Javascript只会用简单的console.log甚至alert,看着真为他们捉鸡。。因为大多数同学追求优雅而高效地写代码,却忽略了如何优雅而高效地调试代码,不得不说是有点“偏科”了。下面我就分享一些实用且聪明的调试技巧,希望能让大家调试自己代码的时候更加从容自信。 1. 不要使用alert首先,alert只能打印出字符串,如果打印的对象不是String,则会调用toString()方法将该对象转成字符串(比如转成[object Object]这种),所以除非你打印String类型的对象,其他什么信息都获取不到。其次,alert会阻塞UI和javascript的执行,必须点击'OK'按钮才能继续,非常低效。所以,喜欢使用alert的同学可以改改这个习惯了。 2. 学会使用console.logconsole.log谁都会用,但是很多同学只知道最简单的console.log(x)这样打印一个对象,当你的代码里面console.log多了之后,会很难将某条打印结果和代码对应,所以我们可以给打印信息加上一个标签便于区分: let x = 1;console.log('aaaaaaaa', x);得到: 标签不一定要有明确的含义,视觉效果显著就可以了,当然有明确意义更好。 事实上,console.log可以接收任意多的参数,最后将这些对象拼接输出,比如: 如果打印信息过多,不容易找到目标信息的话,可以在控制台中进行过滤: 注意点 在使用console.log打印一个引用类型(比如数组和自定义对象)的对象的时候,输出结果可能并不是执行console.log方法那个时间点的值。举个例子: 可以发现两个console.log输出的结果展开后都是[1, 2, 3, 4],因为数组是引用类型,所以在展开后获取到的都是数组最新的状态。我们可以使用JSON.parse(JSON.stringify(...))来解决这个问题: 3. 学会使用console.dir我们有时候想看看一个DOM对象里面到底有什么属性和方法,但是常规的console.log打印出来的只是HTML标签,就像这样: 和直接审查元素没有什么区别。 如果我们想看到DOM对象作为JavaScript对象的结构可以使用console.dir,比如: 事实上,console.dir可以打印出任何JavaScript对象的属性列表,比如打印一个方法: 4. 学会使用console.table我们经常会遇到这样的场景:获取到一个用户列表,每个用户有很多属性,但是我们只想查看其中的某些属性,在用console.log打印出来的时候需要把每个用户对象展开一个个查看,非常麻烦。而console.table完美的解决这个问题,比如我只想获取到下列用户的id和坐标: console.log打印结果: console.table打印结果: 非常的准确和快速! 5. 学会使用console.time有时候我们想知道一段代码的性能或者一个异步方法需要运行多久,这时候需要用到定时器,JavaScript提供了现成的console.time方法,例如: 6. 使用debugger打断点有时候我们需要打断点进行单步调试,一般会选择在浏览器控制台直接打断点,但这样还需要先去Sources里面找到源码,然后再找到需要打断点的那行代码,比较费时间。使用debugger关键词,我们可以直接在源码中定义断点,方便很多,比如: 7. 查到源码文件有时候我们想在控制台的Sources中查找某个js源文件,要把文件夹逐一点开找,非常麻烦。其实Chrome提供了文件的搜索功能,只不过大部分时候我们给忽略了。。 只要按Command + P(windows的快捷键请自行查看)就能弹出搜索框搜索你想要找的文件啦: 8. 压缩JS文件的阅读有时候我们需要在Sources中阅读一段js代码,但是发现它被压缩了,Chrome也提供了和方便的格式化工具,让代码变得重新可读: 点完之后变成这样: 以上就是我个人在平时比较常用的一些调试小技巧,如果大家有其他好的调试技巧也欢迎分享,谢谢????!

June 14, 2019 · 1 min · jiezi

spydebugger-Charles-移动端调试

简介 移动端调试一直都是一个痛点,因为移动终端对于我们来说是一个黑盒,它无法像PC端一样,我们可以通过F12很方便的调出开发者工具。在开发中经常会遇到同样一份代码在某个型号的手机上运行出现错误,其他手机都好好的,开发的时候Chrome上也没有报错。如果没有调试工具这种情况下我们就很难定位问题,接下来的主题就是介绍如何使用spy-debugger + Charles进行移动端调试。 安装第1步:全局安装 spy-debugger npm install spy-debugger -gspy-debugger 证书其实spy-debugger的代理是基于node-mitmproxy模块实现的,这里安装的证书其实是node-mitmproxy的证书,标题写spy-debugger证书是为了和Charels证书区分开来避免混淆。 电脑安装证书第1步:在命令行中执行spy-debugger启动spy-debugger服务,启动成功后,检查你的用户目录(home目录),会发现多了一个node-mitmproxy文件夹,这个文件夹内放的就是代理需要的证书。 我Mac电脑完整的路径是:/Users/jameswain/node-mitmproxy 第2步:在启动spy-debugger服务的电脑上安装证书,双击node-mitmproxy.ca.crt文件 第3步:双击node-mitmproxy CA 选择为 始终信任 第4步:输入你电脑的用户密码 出现这个+号表示证书已经安装成功 IOS手机安装证书第1步:首先需要将node-mitmproxy.ca.crt上传到手机上,可以通过live-server 在node-mitmproxy.ca.crt文件所在的目录下启动这个服务。如果你还没有live-server命令,可以通过以下命令进行安装: npm i -g live-server在/Users/jameswain/node-mitmproxy目录下执行live-server命令 第2步:在手机浏览器上访问这个服务,输入我电脑的IP地址和端口进行访问,⚠️手机和电脑必须是连接同一个WiFi网络才可以访问。 点击node-mitmproxy.ca.crt文件进行下载安装 第3步:在手机的 设置 > 通用 > 描述文件与设备管理 找到node-mitmproxy CA 证书,并点击安装 输入手机锁屏密码: 选择安装 第4步:在手机的 设置 > 通用 > 关于本机 > 证书信任设置 将 node-mitmproxy CA 打开 此时,spy-debugger的前期准备工作就已经全部完成了 Charles 证书这里简单介绍一下Charles的证书安装,如果你已经是Charles的老手了,可以直接跳过。Charles如果不安装证书的话是无法抓https的请求的。 ...

June 13, 2019 · 1 min · jiezi

使用vscode调试你的node应用

都9102年了, 你的nodejs应用还在用console调试吗?从一开始使用 webstorm 内置的 debug 功能, 到使用node-inspector库进行调试顺便脱离 webstorm 的笨重, 再后来 nodejs 内置了debugger 模块也可以帮助调试我们的应用. 目前个人使用 vscode 进行日常开发, 本文主要介绍 vscode 平台的 debugger 调试功能. vscode 本身就内置了 nodejs 的 debug 支持, 除此之外还有有非常多 debug 的扩展插件可供安装使用. 可以点击调试菜单 -> 安装调试附加器, 会自动去到下载插件的页面, 并筛选出debugger类型的插件, 按下载量进行排序. 不仅支持 nodejs/js 的调试, 如 C/C++, python, go 等都有相应 debugger 插件, 一般而言下载量更多都会比较靠谱. 而我们主要是为了调试 nodejs 应用, 就不需要额外去下载插件了. 快速对当前文件进行 debug要对当前打开的文件进行 debug 在 vscode 是非常简单的事, 只需要按快捷F5或在编辑器左侧 debug 面板按下启动的按钮, 然后选择 debug 类型即可. ...

May 14, 2019 · 2 min · jiezi

如何提高后台服务应用问题的排查效率日志-VS-远程调试

转眼间,距离Jerry最近一篇文章推送已经过去了一个多月的时间了。 公众号更新的频率降低,不是因为Jerry偷懒,而是由于从春节过后,我所在的SAP成都研究院数字创新空间整个团队,一直在忙一个5月份需要交付的项目上。 Jerry每天的工作量像下面这张图这样: 这个项目里Jerry负责的是后台开发工作,我用nodejs开发了若干微服务,每个微服务实现一个特定的业务逻辑。这些微服务由Jerry另外开发的一个编排器(Orchestra)统一调度。整套后台实现部署在亚马逊云平台(Amazon Web Service,以下简称AWS)上。 离交付日期越来越近了,我们的功能也赶得差不多了。本地测试运行得很好的场景,部署到AWS上运行后出现了一些bug。比如昨天就遇到一个棘手的bug,因此有了今天这篇文章。 2014年五一节的前一天,当时Jerry还在SAP CRM开发团队工作,负责处理SAP CRM中间件的一个bug。这个bug和代码执行时序有关,每执行一次只有40%的几率能重现,花了我整整一天(8个小时)的时间调试。因为重现bug的场景太复杂,需要调试的ABAP代码量太大,所以让我印象深刻。那个bug处理完之后,我也对自己花了8小时才搞定该bug的效率很不满意,因此写了一篇博客总结这次排错的经验教训: My Tips about how to handle complex and tricky issues https://blogs.sap.com/2014/05... 回到昨天我遇到的在AWS上出现的bug,根据问题的表象,一开始我和负责前端开发的同事,连这个问题出在前端还是后端都没办法判断。当微服务部署在本地并进行测试时一切正常,只有部署在AWS上进行集成测试时才会暴露,而运行在AWS上的nodejs应用,我昨天还不知道如何调试,因此只好采用我大二刚学C语言编程时用过的最笨的排查办法:打日志。 2001年,在结束了一年的计算机专业基础课学习后,Jerry开始了Unix环境下C语言编程的学习。当时我对gdb这种以命令提示行方式进行的调试风格很不适应,大多数时候的排错采用的还是在代码里添加printf语句打印变量内容的方式来进行,被寝室的同学鄙视了好久。 于是昨天我继续采用了这种自己18年前就曾经用过的排错方式: 1. 在可能引起bug的相关代码处逐一加上日志输出语句 2. 执行会出现bug的用户操作 3. 阅读AWS上生成的日志语句 上述三个步骤是一个不断迭代的过程。最开始我加了若干日志输出语句,执行操作后阅读生成的日志,发现没有任何异常。于是不断地增加新的日志打印代码,最后导致了执行一次操作,会生成1200行的日志输出。 我和负责前端开发的同事两人坐在显示器前,一行行检查这海量的日志输出。由于问题是用户第二次操作后才会暴露,每次操作会生成不同的会话,我们被迫不断的上下滑动屏幕来比较这两次会话的uuid和相关的WebSocket uuid等变量。Jerry很快发现,眼睛一眨不眨地盯着显示器逐条检查日志,时间一长眼睛就痛得受不了。无奈之下,只得把这些日志用打印机打印出来,用不同颜色的笔标注出两个会话对应的各种变量,在纸上来回比对。于是就有了下面这些纸张: 虽然最后用这种办法,成功排除了后台出错的可能性,使我们得以把精力花在前台代码的审查上,但是像我一个同事评价的,“这种方式太不环保了”,并且我自己也觉得,效率太低了。 后来好几位热心的同事告诉Jerry,就算运行在SAP Cloud Platform或者AWS这些云平台上的nodejs应用,也是可以单步调试的,Jerry Google了一下,发现远程调试确实很简单,就两条命令而已。 Jerry用我们创新空间团队另外一位同事Haytham开发并部署在AWS上的一个nodejs应用为例来尝试如何在我的本地电脑上对其进行调试。 Haytham虽然是一个大四本科生,但是已经在SAP成都研究院Jerry所在团队实习将近十个月的时间了,最近三个月一直在SAP德国总部参与一个项目的开发。 等Haytham回到成都后,会将自己这十个月的工作感悟,从一个SAP新人的视角给大家分享出来,敬请期待。 Haytham之前写过的文章: SAP成都研究院许聚龙:Hello, Coresystems! Haytham写的这个nodejs应用实际上是Github Webhook的一部分。我们在本地进行微服务nodejs开发,本地git客户端推送代码到远端github仓库。然后需要在AWS上手动git pull把最新的代码拉下来,再用一个开源工具pm2进行微服务部署。Haytham写的这个nodejs应用,能实现本地git推送完毕后一切后续流程的完全自动化,节省了我们大量的部署时间。 下面就来对Haytham这个运行在AWS上的nodejs应用进行远程调试。 1. 用node --inspect-brk在AWS上以调试模式启动应用。 之后控制台上的输出表明有一个nodejs进程以WebSocket协议在127.0.0.1:9229这个地址上监听调试客户端的连接。 2. 我在我的本地电脑上,用如下命令行将我本地电脑的端口9221映射到AWS调试进程监听的9229端口上: ssh -i C:Usersi042416.sshKOI.pem -L 9221:localhost:9229 ubuntu@ec2-us-east-2.compute.amazonaws.com 现在,本地电脑上Chrome浏览器地址栏chrome://inspect里指定监听地址为localhost:9221,  通过第二步建立的SSH tunnel, 我就可以用本地电脑连接到AWS上的nodejs应用并进行调试了。 现在终于可以在Chrome开发者工具里进行愉快的调试了: 因为我平时本地做nodejs开发和调试时,更喜欢用Visual Studio Code,所以下一步我准备试试用Visual Studio Code进行远程调试。 说到Visual Studio Code,Jerry突然想起今天在网上看到的一个关于这个IDE的有意思的扩展,名为"超越鼓励师"。 Jerry试着在自己的Visual Studio Code扩展安装栏里搜索了一下,这个扩展还真的可以下载。不过扩展里出现的"杨超越",Jerry又孤陋寡闻了,咨询了老婆后才知道她是谁。 至于实际效果如何,Jerry不做评价,欢迎Visual Studio Code爱好者自行下载体验。 ...

May 9, 2019 · 1 min · jiezi

Java进程CPU占用率100%问题排查

100%指的是占用了CPU一个核心,两个核心是200%,以此类推。CPU占用率及对应进程ID(pid)可以通过top命令确定,在top界面按 c (显示完整的命令行参数),按 1 (显示每个核心的统计数据)。这个问题最常见的有以下几种可能:1、堆内存不足导致频繁Full GC可以通过两个命令确定sudo jmap -heap pid 查看堆内存的消耗情况sudo jstat -gc pid interval count 查看GC情况,示例:sudo jstat -gc 5746 3000 5 代表查看5746进程的GC情况、每隔3000毫秒打印一次、总共打印5次。如果FGC/FGCT增长明显,说明Full GC很频繁。后续处理:如果情况紧急,那得马上重启Java应用进程不紧急的话需要获取相关信息用于分析为什么堆内存被消耗完了,可能有内存泄漏问题,可以用 1)sudo jmap -histo pid | head -n 20 查看Java对象的占用统计信息,2)sudo jmap -dump:live,format=b,file=heap.bin pid 把堆转储导出到本地文件,可以用 Eclipse MAT 工具分析内存泄漏2、代码实现问题思路:追查具体是哪个线程占用了CPU,1)先查到本地系统CPU占用率高的线程ID,2)找到对应的Java线程及线程堆栈top -H -p pid 查看某个进程里面哪些线程占用了CPU,把对应的线程ID拷贝下来,转为十六进制【IDEA》Tools》Groovy Console》println Long.toHexString(1234) 即可完成转换】。sudo jstack -l -F pid | less 获取Java线程堆栈,用十六进制的本地线程ID搜索,会在某一行的nid处找到对应的线程。查看Java线程堆栈,找到对应的Java类及行号,然后阅读代码查找可能的问题原因。jstack堆栈信息里tid/nid的说明https://docs.oracle.com/javas…The thread dump consists of the thread stack, including the thread state, for all Java threads in the virtual machine.The header line contains the following information about the thread:- Thread ID (tid), which is the address of a thread structure in memory.- ID of the native thread (nid). ...

March 18, 2019 · 1 min · jiezi

汇编基本命令整理

今晚上汇编,因为下课很无聊所以老猪我抽空整理了一下汇编的基本命令,发上来给大家分享一下 ^ _ ^-r 查看、改变CPU寄存器的内容(1)查看CPU寄存器里面的内容-r (2)改变寄存器里面的内容-r axAX 0000:1111-rcs-rip-d 查看内存中的内容(1)查看指定内存位置中的内容查看内存10000H处的内容-d 1000:0-d 1000:0 f-e 改写内存中的内容(1)从内存10010的位置开始改写-e 1000:10(2)从内存10000位置开始写入数值1、字符"a"……-e 1000:0 1 ‘a’ 2 ‘b’ 3 ‘c’(3)向内存中写入字符串-e 1000:0 1 “a+b” 2 “c++” 3 “IBM”(4)将机器码写入内存中-e 1000:0 b8 01 00 b9 02 00 01 c8b80100 mov ax,0001b90200 mov cx,000201c8 add ax,cx-u 将命令翻译为汇编指令-u 1000:0-t 执行CS:IP指向的命令-a 以汇编命令的形式在内存中写入机器命令-a 1000:01000:0000 mov ax,11000:0003 mov bx,2

March 6, 2019 · 1 min · jiezi

微信下调试H5页面

Android端微信1、首先打开,http://debugx5.qq.com 或者扫描下面二维码2、打开微信 TBS 调试3、然后在谷歌浏览器地址栏输入chrome://inspect/#devices出现如下界面4、点击想要调试的页面下的inspect即可

March 6, 2019 · 1 min · jiezi

docker环境下,使用phpstorm进行debug

在上一篇文章中,阐述了在phpstorm安装xdebug。实际的开发过程中,由于历史项目的存在,不同框架的存在,我们需要借助docker来快速的实现开发环境的部署与统一,本文将阐述如何在docker下实现项目的xdebug。理论概述与在本机直接开发不同,docker环境下,大体是这样。宿主机,即我们开发用的电脑。我们看到,有以下几点不同:PHP环境不同本机开发时。项目的运行环境与IDEA上的CLI,都是本机环境,相统一。docker开发时,本机环境与dokcer环境可能不统一。项目的路径不同本机开发时,xdebug反馈的项目路径,就是开发机的实际路径。docker环境下,xdebug将docker主机的路径发送给宿主机,但宿主机接收到,在本机上的此路径上,找不到对应的文件。当然,也就没有办法进行正确的信息显示。远程地址不同本机开发时,远程主机地址就是本机地址,所以是127.0.0.1。docker开发时,远程主机地址,应该是宿主机地址。实施总结出上面的几点不同后,开始实施也变得简单了。统一PHPSTORM与docker的PHP环境配置 -> Languages .. -> PHPCLI Interpreter … -> + -> From Docker Vagrant如果不清楚PHP的路径的话,进行DOCKER容器,使用whereis php。如果在service找不到docker,需要进入配置 -> docker -> + -> 确定,则phpstorm会自动为我们找到当前存在的容器。映射路径配置 -> Languages .. -> PHP -> SERVICES -> +前面提本地项目路径,后面对应docker项目路径。注意:为了保持统一,在docker容器配置时,应该使用volumes来进行磁盘映射。修改远程地址修改docker容器中的,php.ini中的xdebug.remote_host=host.docker.internalhost.docker.internal代表:宿主机添加项目配置信息总结弄懂原理,善于看日志才是解决问题的捷径。

February 27, 2019 · 1 min · jiezi

线上debug指南【草稿】

February 12, 2019 · 0 min · jiezi

远程Debug Java进程的方法

原文地址远程debug的意思是启动一个Java进程,启动一个debugger进程,将两者连接起来,利用debugger来debug Java进程。事实上目前所有的IDE的debug功能都是通过远程debug方式来实现的,它们都利用了一个叫做JDPA(Java Platform Debugger Architecture)的技术。利用JDPA我们除了能够在IDE开发的时候debug,也能够将IDE attach到一个生产环境上正在运行的Java进程做debug(事实上这两个场景在本质上是一样的)。下面会用两个例子来说明如何使用Intellij IDEA来debug一个Java进程。debug一个简单的Java应用我们做了一个很简单的Java应用,它启动后会每隔2秒打印出一个不断增长的数字。源代码在Github debug-simple-app:执行mvn clean package打包执行java -jar target/debug-simple-app.jar运行现在我们要用IDEA远程Debug它。我们先ctrl+c把进程停止掉。1)把项目导入到IDEA里,因为如果没有源码的话我们没有办法打断点2)按照下面步骤新建一个Remote Run/Debug Configuration:选择Remote 除了改个名字,设定Use module classpath,其余的选项不需要修改,直接用默认的就行这里解释一下各种参数:Debugger mode:debugger的模式,有两种:attach和listen。attach的意思是debugger连接到被debug的Java进程,是主动式的。listen的意思是debugger监听由Java进程发送过来的通信,是被动式的。Host和Port的设定了被debug的Java进程的Host和Port,实际上这也告诉我们,远程Debug是通过网络进行的。JDK选项可根据你的不同JDK版本来构造不同的Command line arguments for remote JVM。Command line arguments for remote JVM这个文本框你是不能修改的,它告诉了你如果要这个Java进程能够被远程Debug,那么必须添加这些参数才可以。 所以你要把这里的参数复制出来,后面会用得着。Use module classpath,该选项设定使用那个module的源代码来debug。3)把刚才的Command line arguments for remote JVM添加到刚才的运行命令。像这样:java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar target/debug-simple-app.jar4)点击下图里的Debug按钮开始debug你会发现Console里出现这么一句话Connected to the target VM, address: ’localhost:5005’, transport: ‘socket’,这说明debugger已经attach成功了。5)在debug-simple-app里的代码打个断点看看效果。debug一个tomcat应用实际上debug一个tomcat应用和前面的例子没有什么大的区别。我们写了一个很简单的Servlet,它会返回Hello World以及被访问的次数。源代码在Github debug-tomcat-app:执行mvn clean package打包把target/debug-tomcat-app.war丢到tomcat然后访问http://localhost:8080/debug-tomcat-app/hello查看结果现在我们要用IDEA来debug,那么先把tomcat停掉。1)同样需要把项目导入到IDEA里2)执行tomcat的bin/catalina.sh jpda start,让tomcat可以被debug3)执行jps -v | grep Bootstrap找到Tomcat进程:76905 Bootstrap -Djava.util.logging.config.file=… -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n -Dcatalina.base=… -Dcatalina.home=… -Djava.io.tmpdir=…注意上面的-agentlib…address=localhost:8000参数,记住这个端口4)和前面的例子一样,新建一个Remote Run/Debug Configuration,把端口设定为8000,然后启动5)然后打个断点试试如果你想改变Tomcat的端口怎么做?看看bin/catalina.sh你会发现这么一段注释JPDA_TRANSPORT (Optional) JPDA transport used when the “jpda start” command is executed. The default is “dt_socket”.JPDA_ADDRESS (Optional) Java runtime options used when the “jpda start” command is executed. The default is localhost:8000.JPDA_SUSPEND (Optional) Java runtime options used when the “jpda start” command is executed. Specifies whether JVM should suspend execution immediately after startup. Default is “n”.JPDA_OPTS (Optional) Java runtime options used when the “jpda start” command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS, and JPDA_SUSPEND are ignored. Thus, all required jpda options MUST be specified. The default is: -agentlib:jdwp=transport=$JPDA_TRANSPORT, address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND所以你只需要提供JPDA_ADDRESS环境变量参数就行了。比如这样:JPDA_ADDRESS=5005 bin/catalina.sh jpda start参考文档Debug your Java code with ease using JPDAJPDA Connection and InvocationOracle VM Invocation Options ...

October 10, 2018 · 1 min · jiezi