当前位置: 首页 > news >正文

摄影网站设计理念免费软件下载中心

摄影网站设计理念,免费软件下载中心,毕设做桌面软件还是网站,WordPress怎么文章分类文章目录 dashboardwatchretransform 前面介绍了 arthas 启动相关的代码并聊了聊怎么到一个 shellserver 的建立。 本篇我们来探讨一下几个使用频次非常高的命令是如何实现的。 dashboard 想看这个命令的主要原因是编程这些年来从来没有开发过 terminal 的这种比较花哨的界面和 top 命令一样。 public void process(final CommandProcess process) {Session session process.session();timer new Timer(Timer-for-arthas-dashboard- session.getSessionId(), true);// ctrl-C supportprocess.interruptHandler(new DashboardInterruptHandler(process, timer));/** 通过handle回调在suspend和end时停止timerresume时重启timer*/HandlerVoid stopHandler new HandlerVoid() {Overridepublic void handle(Void event) {stop();}};HandlerVoid restartHandler new HandlerVoid() {Overridepublic void handle(Void event) {restart(process);}};process.suspendHandler(stopHandler);process.resumeHandler(restartHandler);process.endHandler(stopHandler);// q exit supportprocess.stdinHandler(new QExitHandler(process));// start the timertimer.scheduleAtFixedRate(new DashboardTimerTask(process), 0, getInterval());}获取会话 Session session process.session();调用process对象的session方法获取当前会话对象并赋值给session变量。process 创建定时器 timer new Timer(Timer-for-arthas-dashboard- session.getSessionId(), true);创建一个定时器对象命名为Timer-for-arthas-dashboard- session.getSessionId()其中session.getSessionId()获取会话ID。 定时器的主要作用是进行界面刷新。第二个参数true表示这个定时器是守护线程当所有非守护线程结束时程序会自动退出。 处理中断 process.interruptHandler(new DashboardInterruptHandler(process, timer));设置一个中断处理器DashboardInterruptHandler用于处理中断信号如CtrlC。 处理挂起、恢复和结束事件 HandlerVoid stopHandler new HandlerVoid() {Overridepublic void handle(Void event) {stop();} };HandlerVoid restartHandler new HandlerVoid() {Overridepublic void handle(Void event) {restart(process);} }; process.suspendHandler(stopHandler); process.resumeHandler(restartHandler); process.endHandler(stopHandler);定义了两个处理器stopHandler和restartHandler分别用于处理挂起、恢复和结束事件。stopHandler调用stop方法停止定时器。restartHandler调用restart(process)方法重新启动定时器。将这些处理器分别注册到process对象的suspendHandler、resumeHandler和endHandler中。 处理退出命令 process.stdinHandler(new QExitHandler(process));设置一个标准输入处理器QExitHandler用于处理退出命令如输入q。 启动定时器 timer.scheduleAtFixedRate(new DashboardTimerTask(process), 0, getInterval());使用timer对象定期执行DashboardTimerTask任务。周期性执行 DashboardTimerTask 统计信息从 jvm 的 MXBean 中获取并组装 dashboardModel 再后面跟踪就能发现界面绘制是属于 ProcessImpl 对命令结果的处理发现没有arthas 是一个很完整的解耦设计职责分明。如何绘制界面在 view 文件夹比如该命令 再往后看界面就是做的以行为单元的字符串输出到标准输出中stdout。 watch 下面的 watch 命令在分析性能问题是出场率最高的命令极大的释放了开发的背锅压力。 WatchCommand 继承了 EnhancerCommand 下面的代码就是增强的核心代码。一般来说我们都知道使用 javaagent 可以在加载到jvm之前做增强也就是 premain 方法但 jvm也提供了 attach 的增强即 agentmain这也是在上一篇中提到过的 protected void enhance(CommandProcess process) {Session session process.session();if (!session.tryLock()) {String msg someone else is enhancing classes, pls. wait.;process.appendResult(new EnhancerModel(null, false, msg));process.end(-1, msg);return;}EnhancerAffect effect null;int lock session.getLock();try {Instrumentation inst session.getInstrumentation();AdviceListener listener getAdviceListenerWithId(process);if (listener null) {logger.error(advice listener is null);String msg advice listener is null, check arthas log;process.appendResult(new EnhancerModel(effect, false, msg));process.end(-1, msg);return;}boolean skipJDKTrace false;if(listener instanceof AbstractTraceAdviceListener) {skipJDKTrace ((AbstractTraceAdviceListener) listener).getCommand().isSkipJDKTrace();}Enhancer enhancer new Enhancer(listener, listener instanceof InvokeTraceable, skipJDKTrace, getClassNameMatcher(), getClassNameExcludeMatcher(), getMethodNameMatcher());// 注册通知监听器process.register(listener, enhancer);effect enhancer.enhance(inst, this.maxNumOfMatchedClass);if (effect.getThrowable() ! null) {String msg error happens when enhancing class: effect.getThrowable().getMessage();process.appendResult(new EnhancerModel(effect, false, msg));process.end(1, msg , check arthas log: LogUtil.loggingFile());return;}if (effect.cCnt() 0 || effect.mCnt() 0) {// no class effectedif (!StringUtils.isEmpty(effect.getOverLimitMsg())) {process.appendResult(new EnhancerModel(effect, false));process.end(-1);return;}// might be method code too largeprocess.appendResult(new EnhancerModel(effect, false, No class or method is affected));String smCommand Ansi.ansi().fg(Ansi.Color.GREEN).a(sm CLASS_NAME METHOD_NAME).reset().toString();String optionsCommand Ansi.ansi().fg(Ansi.Color.GREEN).a(options unsafe true).reset().toString();String javaPackage Ansi.ansi().fg(Ansi.Color.GREEN).a(java.*).reset().toString();String resetCommand Ansi.ansi().fg(Ansi.Color.GREEN).a(reset CLASS_NAME).reset().toString();String logStr Ansi.ansi().fg(Ansi.Color.GREEN).a(LogUtil.loggingFile()).reset().toString();String issueStr Ansi.ansi().fg(Ansi.Color.GREEN).a(https://github.com/alibaba/arthas/issues/47).reset().toString();String msg No class or method is affected, try:\n 1. Execute smCommand to make sure the method you are tracing actually exists (it might be in your parent class).\n 2. Execute optionsCommand , if you want to enhance the classes under the javaPackage package.\n 3. Execute resetCommand and try again, your method body might be too large.\n 4. Match the constructor, use init, for example: watch demo.MathGame init\n 5. Check arthas log: logStr \n 6. Visit issueStr for more details.;process.end(-1, msg);return;}// 这里做个补偿,如果在enhance期间,unLock被调用了,则补偿性放弃if (session.getLock() lock) {if (process.isForeground()) {process.echoTips(Constants.Q_OR_CTRL_C_ABORT_MSG \n);}}process.appendResult(new EnhancerModel(effect, true));//异步执行在AdviceListener中结束} catch (Throwable e) {String msg error happens when enhancing class: e.getMessage();logger.error(msg, e);process.appendResult(new EnhancerModel(effect, false, msg));process.end(-1, msg);} finally {if (session.getLock() lock) {// enhance结束后解锁process.session().unLock();}}}这个方法的核心就在这几行代码中 Enhancer enhancer new Enhancer(listener, listener instanceof InvokeTraceable, skipJDKTrace, getClassNameMatcher(), getClassNameExcludeMatcher(), getMethodNameMatcher());// 注册通知监听器process.register(listener, enhancer);effect enhancer.enhance(inst, this.maxNumOfMatchedClass);/*** 对象增强** param inst inst* param maxNumOfMatchedClass 匹配的class最大数量* return 增强影响范围* throws UnmodifiableClassException 增强失败*/public synchronized EnhancerAffect enhance(final Instrumentation inst, int maxNumOfMatchedClass) throws UnmodifiableClassException {// 获取需要增强的类集合this.matchingClasses GlobalOptions.isDisableSubClass? SearchUtils.searchClass(inst, classNameMatcher): SearchUtils.searchSubClass(inst, SearchUtils.searchClass(inst, classNameMatcher));if (matchingClasses.size() maxNumOfMatchedClass) {affect.setOverLimitMsg(The number of matched classes is matchingClasses.size() , greater than the limit value maxNumOfMatchedClass . Try to change the limit with option -m arg.);return affect;}// 过滤掉无法被增强的类ListPairClass?, String filtedList filter(matchingClasses);if (!filtedList.isEmpty()) {for (PairClass?, String filted : filtedList) {logger.info(ignore class: {}, reason: {}, filted.getFirst().getName(), filted.getSecond());}}logger.info(enhance matched classes: {}, matchingClasses);affect.setTransformer(this);try {ArthasBootstrap.getInstance().getTransformerManager().addTransformer(this, isTracing);// 批量增强if (GlobalOptions.isBatchReTransform) {final int size matchingClasses.size();final Class?[] classArray new Class?[size];arraycopy(matchingClasses.toArray(), 0, classArray, 0, size);if (classArray.length 0) {inst.retransformClasses(classArray);logger.info(Success to batch transform classes: Arrays.toString(classArray));}} else {// for each 增强for (Class? clazz : matchingClasses) {try {inst.retransformClasses(clazz);logger.info(Success to transform class: clazz);} catch (Throwable t) {logger.warn(retransform {} failed., clazz, t);if (t instanceof UnmodifiableClassException) {throw (UnmodifiableClassException) t;} else if (t instanceof RuntimeException) {throw (RuntimeException) t;} else {throw new RuntimeException(t);}}}}} catch (Throwable e) {logger.error(Enhancer error, matchingClasses: {}, matchingClasses, e);affect.setThrowable(e);}return affect;}增强的关于字节码增强部分在 WatchAdviceListener 中相当于做了一个 AOP。而这些 AdviceListenerAdapter 的调用链 SpyImpl ---- SpyAPI — SpyInterceptors — Enhancer.transform class WatchAdviceListener extends AdviceListenerAdapter {private static final Logger logger LoggerFactory.getLogger(WatchAdviceListener.class);private final ThreadLocalWatch threadLocalWatch new ThreadLocalWatch();private WatchCommand command;private CommandProcess process;public WatchAdviceListener(WatchCommand command, CommandProcess process, boolean verbose) {this.command command;this.process process;super.setVerbose(verbose);}private boolean isFinish() {return command.isFinish() || !command.isBefore() !command.isException() !command.isSuccess();}Overridepublic void before(ClassLoader loader, Class? clazz, ArthasMethod method, Object target, Object[] args)throws Throwable {// 开始计算本次方法调用耗时threadLocalWatch.start();if (command.isBefore()) {watching(Advice.newForBefore(loader, clazz, method, target, args));}}Overridepublic void afterReturning(ClassLoader loader, Class? clazz, ArthasMethod method, Object target, Object[] args,Object returnObject) throws Throwable {Advice advice Advice.newForAfterReturning(loader, clazz, method, target, args, returnObject);if (command.isSuccess()) {watching(advice);}finishing(advice);}Overridepublic void afterThrowing(ClassLoader loader, Class? clazz, ArthasMethod method, Object target, Object[] args,Throwable throwable) {Advice advice Advice.newForAfterThrowing(loader, clazz, method, target, args, throwable);if (command.isException()) {watching(advice);}finishing(advice);}private void finishing(Advice advice) {if (isFinish()) {watching(advice);}}private void watching(Advice advice) {try {// 本次调用的耗时double cost threadLocalWatch.costInMillis();boolean conditionResult isConditionMet(command.getConditionExpress(), advice, cost);if (this.isVerbose()) {process.write(Condition express: command.getConditionExpress() , result: conditionResult \n);}if (conditionResult) {// TODO: concurrency issues for process.writeObject value getExpressionResult(command.getExpress(), advice, cost);WatchModel model new WatchModel();model.setTs(new Date());model.setCost(cost);model.setValue(new ObjectVO(value, command.getExpand()));model.setSizeLimit(command.getSizeLimit());model.setClassName(advice.getClazz().getName());model.setMethodName(advice.getMethod().getName());if (advice.isBefore()) {model.setAccessPoint(AccessPoint.ACCESS_BEFORE.getKey());} else if (advice.isAfterReturning()) {model.setAccessPoint(AccessPoint.ACCESS_AFTER_RETUNING.getKey());} else if (advice.isAfterThrowing()) {model.setAccessPoint(AccessPoint.ACCESS_AFTER_THROWING.getKey());}process.appendResult(model);process.times().incrementAndGet();if (isLimitExceeded(command.getNumberOfLimit(), process.times().get())) {abortProcess(process, command.getNumberOfLimit());}}} catch (Throwable e) {logger.warn(watch failed., e);process.end(-1, watch failed, condition is: command.getConditionExpress() , express is: command.getExpress() , e.getMessage() , visit LogUtil.loggingFile() for more details.);}} }Enhance 是个自定义的 ClassTransformer 在 Instrumentation 进行 addTransformer 时将 enhance 增强纳进管理在 redefined 或者 retransformed 的时候调用 transform 方法。。 Instrumentation 的方法 retransform retransform 这个命令的牛逼之处是可以进行灵活的热加载用过 jrebel 的同学应该比较清除在开发时能使用热加载compile 一下修改的功能就能生效在开发时能节省大量的时间。 在arthas 中 jad–mc–retransform 工具链实现热加载也是一个在线上快速修复的一个方法。
http://www.zqtcl.cn/news/444083/

相关文章:

  • 大家都在哪些网站上做医药招商wordpress po文件
  • 国外主题网站兰州app
  • 建设项目自主验收公示网站dedecms英文外贸网站企业模板下载
  • 做网站要服务器吗前端企业网站开发
  • 用html写一个个人介绍多网站怎么做seo
  • 做网站打广告犯法吗中国建设投资集团 网站首页
  • 怎么免费申请个人网站职业技能培训有哪些
  • 小型的企业网站湖南备案网站建设方案书
  • 现在做网站公司seo怎么做教程
  • asp化妆品网站windows优化大师有必要安装吗
  • 网站流量分析系统制作图片网站
  • 做网站技术路线广州番禺发布公众号
  • 企业网站自己可以做吗服装网站建设的利益分析
  • 网站做软件居众装饰集团有限公司
  • 南山网站制作联系电话芒果国际影城星沙店
  • 珠海网站设计费用建企业版网站多久
  • linux 网站搬家wordpress 卸载plugin
  • 江苏省建设厅网站 投诉编辑网站的软件手机
  • 深圳地图各区分布图seo网络优化师就业前景
  • 北京网站备案代理国家企业信用信息公示系统广东
  • 推销网站重庆网站优化公司哪家便宜
  • 外贸公司网站搭建礼品网站建设
  • 网站建设 今晟网络中国制造网官网登录
  • 东莞网站设计如何常州做网站设计
  • php网站数据库修改网站备案有必要吗
  • 电商会学着做网站呢WordPress又拍云cdn
  • 网站健设推广产品多少钱网站规划有什么意义
  • 诚信网站备案中心内江网站建设新闻
  • 品牌形象网站有哪些百度应用中心
  • 网站建设找什么工作室甜点网站建设的功能及意义