- 浏览: 7937098 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (2425)
- 软件工程 (75)
- JAVA相关 (662)
- ajax/web相关 (351)
- 数据库相关/oracle (218)
- PHP (147)
- UNIX/LINUX/FREEBSD/solaris (118)
- 音乐探讨 (1)
- 闲话 (11)
- 网络安全等 (21)
- .NET (153)
- ROR和GOG (10)
- [网站分类]4.其他技术区 (181)
- 算法等 (7)
- [随笔分类]SOA (8)
- 收藏区 (71)
- 金融证券 (4)
- [网站分类]5.企业信息化 (3)
- c&c++学习 (1)
- 读书区 (11)
- 其它 (10)
- 收藏夹 (1)
- 设计模式 (1)
- FLEX (14)
- Android (98)
- 软件工程心理学系列 (4)
- HTML5 (6)
- C/C++ (0)
- 数据结构 (0)
- 书评 (3)
- python (17)
- NOSQL (10)
- MYSQL (85)
- java之各类测试 (18)
- nodejs (1)
- JAVA (1)
- neo4j (3)
- VUE (4)
- docker相关 (1)
最新评论
-
xiaobadi:
jacky~~~~~~~~~
推荐两个不错的mybatis GUI生成工具 -
masuweng:
(转)JAVA获得机器码的实现 -
albert0707:
有些扩展名为null
java 7中可以判断文件的contenttype了 -
albert0707:
非常感谢!!!!!!!!!
java 7中可以判断文件的contenttype了 -
zhangle:
https://zhuban.me竹板共享 - 高效便捷的文档 ...
一个不错的网络白板工具
1.使用背景
生产环境系统发生问题时,定位问题需要获取系统运行时的相关数据,如方法参数、返回值、全局变量、堆栈信息等。为了获取这些数据,需要修改代码,将数据输出到日志文件,再发布到生产环境。这种方式,一方面将增大定位问题的成本和周期,对于紧急问题无法做到及时定位及解决;另一方面重新部署后环境很大程度上已被破坏,很难重现问题。BTrace在这种背景环境下应运而生了。
2.BTrace简述
Btrace (Byte Trace)是sun推出的一款Java 动态、安全追踪(监控)工具,可以在不停机的情况下监控系统运行情况,并且做到最少的侵入,占用最少的系统资源。官方网址:https://kenai.com/projects/btrace。BTrace在使用上做了很多限制,如不能创建对象、不能使用数组、不能抛出或捕获异常、不能使用循环、不能使用synchronized关键字、脚本的属性和方法都必须使用static修饰等,具体限制条件可参考用户手册。根据官方声明,不当地使用BTrace可能导致JVM崩溃,如BTrace使用错误的.class文件,所以,可以先在本地验证BTrace脚本的正确性再使用。
3.BTrace优点
安全性:安全性不会导致对目标Java进程的任何破坏性影响;
无侵入性:无需对原有代码做任何修改,降低上线风险和测试成本,并且无需重启系统。
4.安装BTrace
1)下载地址:https://github.com/btraceio/btrace/releases/tag/v1.3.8.3-1
2)解压缩
3)设置环境变量
BTRACE_HOME=/Users/wlxs/btrace-bin-1.3.8.3
export BTRACE_HOME
export PATH=$PATH:$BTRACE_HOME/bin
5.使用btrace
作用:运行Btrace脚本
命令格式:
参数说明:
6.使用btracec
作用:预编译BTrace脚本,在编译期验证脚本正确性。
命令格式:
参数说明:directory指定编译结果输出路径,其它参数同btrace。
7.使用btracer
作用:btracer命令同时启动应用程序和BTrace脚本
命令格式:
参数说明:
8.注解说明
1)类注解
@com.sun.btrace.annotations.BTrace指定该java类为一个btrace脚本文件。
2)属性注解
@TLS标注的属性可以在追踪脚本的方法中通讯
3)方法注解
@OnMethod:指定该方法在什么情况下被执行,clazz属性指定要跟踪的类的全限定类名,也可以用正则表达式,“/类名的Pattern/”匹配,如/javax\\.swing\\..*/;用”+类名”追踪所有子类,如+java.lang.Runnable;用”@xxx”追踪用该注解注解过的类,如@javax.jws.WebService。method属性指定要追踪的方法名称,也可以用正则表达式。location属性用@Location来指定该方法在目标方法执行前(后、异常、某行、某个方法调用)被执行。
@OnTimer:定时执行该方法。
@OnExit:当脚本运行Sys.exit(code)时执行该方法。
@OnError:当脚本运行抛出异常时执行该方法。
@OnEvent:脚本运行时Ctrl+C可以发送事件。
@OnLowMemory:指定一个内存阀值,低于阀值值执行该方法。
@OnProbe:指定一个xml文件来描述在什么时候执行该方法。
4)方法参数注解
@Self:指目标对象本身。
@Retrun:指目标程序方法返回值(需要配合Kind.RETURN)。
@ProbeClassName:指目标类名。
@ProbeMethodName:指目标方法名。
@targetInstance:指@Location指定的clazz和method的目标(需要配合Kind.CALL)。
@targetMethodOrField:指@Location指定的clazz和method的目标的方法或字段(需要配合Kind.CALL)。
@Duration:指目标方法执行时间,单位是纳秒(需要需要配合Kind.RETURN或Kind.ERROR一起使用)。
AnyType:获取对应请求的参数,泛指任意类型。
9.追踪时机参数
Kind.Entry:开始进入目标方法时,默认值。
Kind.Return:目标方法返回时。
Kind.Error:异常没被捕获被抛出目标方法之外时。
Kind.Throw:异常抛出时。
Kind.Catch:异常被捕获时。
Kind.Call:被调用时。
Kind.Line:执行到某行时。
10.其它
1)追踪构造函数用法:@OnMethod(clazz="java.net.ServerSocket",method="<init>”)。
2)追踪静态内部类:在类与内部类之间加上"$"@OnMethod(clazz="com.vip.MyServer$MyInnerClass", method="hello”)。
3)追踪同名函数:如果有多个同名的函数,可以在拦截函数上定义不同的参数列表。
4)追踪结果输出可以使用>将结果输出到指定文件。
11.示例代码
Calculator类的add方法每隔5秒对a、b两个数进行相加,代码如下。
public class Calculator {
private int c = 1;
public int add(int a, int b) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return a + b;
}
}
BTraceDemo调用Calculator的add方法对两个随机数进行相加,代码如下。
public class BTraceDemo {
public static void main(String[] args) {
Calculator calculator = new Calculator();
Random random = new Random();
while (true) {
System.out.println(calculator.add(random.nextInt(10), random.nextInt(10)));
}
}
}
1)BTraceTest则是相应的追踪脚本,代码如下。
@BTrace
public class BTraceTest {
private static long count;
static{
println("---------------------------JVM properties:---------------------------");
printVmArguments();
println("---------------------------System properties:------------------------");
printProperties();
println("---------------------------OS properties:----------------------------");
printEnv();
exit();
}
@OnMethod(
clazz = "Calculator",
method = "add",
location = @Location(Kind.RETURN)
)
public static void trace1(int a, int b, @Return int sum) {
println("trace1:a=" + a + ",b=" + b + ",sum=" + sum);
}
}
运行如下命令:
btrace 11308 /Users/wlxs/java/BTraceTest.java
11308是BTraceDemo的进程ID,静态块中的输出结果就不展示了。trace1方法实现对Calculator类的add方法的入参和返回值进行追踪,结果如下。
trace1:a=2,b=6,sum=8
2)为了节省篇幅,下面都将只列出各个追踪的方法,trace2追踪Calculator类的add方法执行时间,默认时间单位是纳秒。
@OnMethod(
clazz = "Calculator",
method = "add",
location = @Location(Kind.RETURN)
)
public static void trace2(@Duration long duration) {
println(strcat("duration(nanos): ", str(duration)));
println(strcat("duration(s): ", str(duration / 1000000000)));
}
结果如下。
duration(nanos): 5004187000
duration(s): 5
3)trace3追踪Calculator类的add方法,并且追踪add方法中的任何类的sleep方法,代码如下。
@OnMethod(
clazz = "Calculator",
method = "add",
location = @Location(value = Kind.CALL, clazz = "/.*/", method = "sleep")
)
public static void trace3(@ProbeClassName String pcm, @ProbeMethodName String pmn,
@TargetInstance Object instance, @TargetMethodOrField String method) {
println(strcat("ProbeClassName: ", pcm));
println(strcat("ProbeMethodName: ", pmn));
println(strcat("TargetInstance: ", str(instance)));
println(strcat("TargetMethodOrField : ", str(method)));
println(strcat("count: ", str(++count)));
}
结果如下。
ProbeClassName: Calculator
ProbeMethodName: add
TargetInstance: null
TargetMethodOrField : sleep
count: 1
4)trace4每隔6秒打印一次count的值,代码如下。
@OnTimer(6000)
public static void trace4() {
println(strcat("trace4:count: ", str(count)));
}
结果如下。
trace4:count: 1
5)trace5用于获取Calculator类的c属性的值,代码如下。
@OnMethod(
clazz = "Calculator",
method = "add",
location = @Location(Kind.RETURN)
)
public static void trace5(@Self Object calculator) {
println(get(field("Calculator", "c"), calculator));
}
6)traceMemory每隔4秒打印一次印堆和非堆内存信息,代码如下。
@OnTimer(4000)
public static void traceMemory() {
println("heap:");
println(heapUsage());
println("no-heap:");
println(nonHeapUsage());
}
结果如下。
heap:
init = 10485760(10240K) used = 4430576(4326K) committed = 9961472(9728K) max = 9961472(9728K)
no-heap:
init = 24576000(24000K) used = 7813992(7630K) committed = 24576000(24000K) max = 136314880(133120K)
7)trace6每隔4秒检测是否有死锁产生,并打印产生死锁的相关类信息、对应的代码行、线程信息,代码如下。
@OnTimer(4000)
public static void trace6() {
deadlocks();
}
生产环境系统发生问题时,定位问题需要获取系统运行时的相关数据,如方法参数、返回值、全局变量、堆栈信息等。为了获取这些数据,需要修改代码,将数据输出到日志文件,再发布到生产环境。这种方式,一方面将增大定位问题的成本和周期,对于紧急问题无法做到及时定位及解决;另一方面重新部署后环境很大程度上已被破坏,很难重现问题。BTrace在这种背景环境下应运而生了。
2.BTrace简述
Btrace (Byte Trace)是sun推出的一款Java 动态、安全追踪(监控)工具,可以在不停机的情况下监控系统运行情况,并且做到最少的侵入,占用最少的系统资源。官方网址:https://kenai.com/projects/btrace。BTrace在使用上做了很多限制,如不能创建对象、不能使用数组、不能抛出或捕获异常、不能使用循环、不能使用synchronized关键字、脚本的属性和方法都必须使用static修饰等,具体限制条件可参考用户手册。根据官方声明,不当地使用BTrace可能导致JVM崩溃,如BTrace使用错误的.class文件,所以,可以先在本地验证BTrace脚本的正确性再使用。
3.BTrace优点
安全性:安全性不会导致对目标Java进程的任何破坏性影响;
无侵入性:无需对原有代码做任何修改,降低上线风险和测试成本,并且无需重启系统。
4.安装BTrace
1)下载地址:https://github.com/btraceio/btrace/releases/tag/v1.3.8.3-1
2)解压缩
3)设置环境变量
BTRACE_HOME=/Users/wlxs/btrace-bin-1.3.8.3
export BTRACE_HOME
export PATH=$PATH:$BTRACE_HOME/bin
5.使用btrace
作用:运行Btrace脚本
命令格式:
参数说明:
6.使用btracec
作用:预编译BTrace脚本,在编译期验证脚本正确性。
命令格式:
参数说明:directory指定编译结果输出路径,其它参数同btrace。
7.使用btracer
作用:btracer命令同时启动应用程序和BTrace脚本
命令格式:
参数说明:
8.注解说明
1)类注解
@com.sun.btrace.annotations.BTrace指定该java类为一个btrace脚本文件。
2)属性注解
@TLS标注的属性可以在追踪脚本的方法中通讯
3)方法注解
@OnMethod:指定该方法在什么情况下被执行,clazz属性指定要跟踪的类的全限定类名,也可以用正则表达式,“/类名的Pattern/”匹配,如/javax\\.swing\\..*/;用”+类名”追踪所有子类,如+java.lang.Runnable;用”@xxx”追踪用该注解注解过的类,如@javax.jws.WebService。method属性指定要追踪的方法名称,也可以用正则表达式。location属性用@Location来指定该方法在目标方法执行前(后、异常、某行、某个方法调用)被执行。
@OnTimer:定时执行该方法。
@OnExit:当脚本运行Sys.exit(code)时执行该方法。
@OnError:当脚本运行抛出异常时执行该方法。
@OnEvent:脚本运行时Ctrl+C可以发送事件。
@OnLowMemory:指定一个内存阀值,低于阀值值执行该方法。
@OnProbe:指定一个xml文件来描述在什么时候执行该方法。
4)方法参数注解
@Self:指目标对象本身。
@Retrun:指目标程序方法返回值(需要配合Kind.RETURN)。
@ProbeClassName:指目标类名。
@ProbeMethodName:指目标方法名。
@targetInstance:指@Location指定的clazz和method的目标(需要配合Kind.CALL)。
@targetMethodOrField:指@Location指定的clazz和method的目标的方法或字段(需要配合Kind.CALL)。
@Duration:指目标方法执行时间,单位是纳秒(需要需要配合Kind.RETURN或Kind.ERROR一起使用)。
AnyType:获取对应请求的参数,泛指任意类型。
9.追踪时机参数
Kind.Entry:开始进入目标方法时,默认值。
Kind.Return:目标方法返回时。
Kind.Error:异常没被捕获被抛出目标方法之外时。
Kind.Throw:异常抛出时。
Kind.Catch:异常被捕获时。
Kind.Call:被调用时。
Kind.Line:执行到某行时。
10.其它
1)追踪构造函数用法:@OnMethod(clazz="java.net.ServerSocket",method="<init>”)。
2)追踪静态内部类:在类与内部类之间加上"$"@OnMethod(clazz="com.vip.MyServer$MyInnerClass", method="hello”)。
3)追踪同名函数:如果有多个同名的函数,可以在拦截函数上定义不同的参数列表。
4)追踪结果输出可以使用>将结果输出到指定文件。
11.示例代码
Calculator类的add方法每隔5秒对a、b两个数进行相加,代码如下。
public class Calculator {
private int c = 1;
public int add(int a, int b) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return a + b;
}
}
BTraceDemo调用Calculator的add方法对两个随机数进行相加,代码如下。
public class BTraceDemo {
public static void main(String[] args) {
Calculator calculator = new Calculator();
Random random = new Random();
while (true) {
System.out.println(calculator.add(random.nextInt(10), random.nextInt(10)));
}
}
}
1)BTraceTest则是相应的追踪脚本,代码如下。
@BTrace
public class BTraceTest {
private static long count;
static{
println("---------------------------JVM properties:---------------------------");
printVmArguments();
println("---------------------------System properties:------------------------");
printProperties();
println("---------------------------OS properties:----------------------------");
printEnv();
exit();
}
@OnMethod(
clazz = "Calculator",
method = "add",
location = @Location(Kind.RETURN)
)
public static void trace1(int a, int b, @Return int sum) {
println("trace1:a=" + a + ",b=" + b + ",sum=" + sum);
}
}
运行如下命令:
btrace 11308 /Users/wlxs/java/BTraceTest.java
11308是BTraceDemo的进程ID,静态块中的输出结果就不展示了。trace1方法实现对Calculator类的add方法的入参和返回值进行追踪,结果如下。
trace1:a=2,b=6,sum=8
2)为了节省篇幅,下面都将只列出各个追踪的方法,trace2追踪Calculator类的add方法执行时间,默认时间单位是纳秒。
@OnMethod(
clazz = "Calculator",
method = "add",
location = @Location(Kind.RETURN)
)
public static void trace2(@Duration long duration) {
println(strcat("duration(nanos): ", str(duration)));
println(strcat("duration(s): ", str(duration / 1000000000)));
}
结果如下。
duration(nanos): 5004187000
duration(s): 5
3)trace3追踪Calculator类的add方法,并且追踪add方法中的任何类的sleep方法,代码如下。
@OnMethod(
clazz = "Calculator",
method = "add",
location = @Location(value = Kind.CALL, clazz = "/.*/", method = "sleep")
)
public static void trace3(@ProbeClassName String pcm, @ProbeMethodName String pmn,
@TargetInstance Object instance, @TargetMethodOrField String method) {
println(strcat("ProbeClassName: ", pcm));
println(strcat("ProbeMethodName: ", pmn));
println(strcat("TargetInstance: ", str(instance)));
println(strcat("TargetMethodOrField : ", str(method)));
println(strcat("count: ", str(++count)));
}
结果如下。
ProbeClassName: Calculator
ProbeMethodName: add
TargetInstance: null
TargetMethodOrField : sleep
count: 1
4)trace4每隔6秒打印一次count的值,代码如下。
@OnTimer(6000)
public static void trace4() {
println(strcat("trace4:count: ", str(count)));
}
结果如下。
trace4:count: 1
5)trace5用于获取Calculator类的c属性的值,代码如下。
@OnMethod(
clazz = "Calculator",
method = "add",
location = @Location(Kind.RETURN)
)
public static void trace5(@Self Object calculator) {
println(get(field("Calculator", "c"), calculator));
}
6)traceMemory每隔4秒打印一次印堆和非堆内存信息,代码如下。
@OnTimer(4000)
public static void traceMemory() {
println("heap:");
println(heapUsage());
println("no-heap:");
println(nonHeapUsage());
}
结果如下。
heap:
init = 10485760(10240K) used = 4430576(4326K) committed = 9961472(9728K) max = 9961472(9728K)
no-heap:
init = 24576000(24000K) used = 7813992(7630K) committed = 24576000(24000K) max = 136314880(133120K)
7)trace6每隔4秒检测是否有死锁产生,并打印产生死锁的相关类信息、对应的代码行、线程信息,代码如下。
@OnTimer(4000)
public static void trace6() {
deadlocks();
}
发表评论
-
复习:强迫线程顺序执行方式
2019-01-03 23:42 1569方法1: 三个线程,t1,t2,t3,如果一定要按顺序执行, ... -
(转)不错的前后端处理异常的方法
2019-01-02 23:16 2018前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是 ... -
info q的极客时间大咖说等资料下载
2018-08-15 08:40 3465info q的极客时间大咖说等资料下载,还有不少思维导图 链 ... -
CXF 客户端超时时间设置(非Spring配置方式)
2018-07-03 22:38 2232import org.apache.cxf.endpoint. ... -
(转)synchronized关键字画像:正确打开方式
2018-06-14 09:25 490https://mp.weixin.qq.com/s/b3Sx ... -
CountDownLatch的例子
2018-06-13 14:10 684public class StatsDemo { ... -
两道面试题,带你解析Java类加载机制
2018-06-12 16:29 607https://mp.weixin.qq.com/s/YTa0 ... -
Spring中获取request的几种方法,及其线程安全性分析
2018-06-11 09:03 669https://mp.weixin.qq.com/s/KeFJ ... -
内部类小结
2018-06-06 10:25 434https://mp.weixin.qq.com/s/hErv ... -
JVM虚拟机小结1
2018-06-04 20:43 5391 jps -l //列出详细的类名和进程ID 2)jps ... -
windows下自带命令行工具查看CPU资源情况等
2018-06-04 12:53 3097微软提供了不少命令行 ... -
(收藏)深入分析Java的序列化与反序列化
2018-05-30 15:21 614https://mp.weixin.qq.com/s/T2Bn ... -
apache common包中的序列化工具
2018-05-30 09:10 1843什么是序列化 我们的 ... -
JAVA8 JVM的变化: 元空间(Metaspace)
2018-05-24 22:30 963本文将会分享至今为至我收集的关于永久代(Permanent G ... -
(转)服务器性能指标(一)——负载(Load)分析及问题排查
2018-05-21 21:03 1360原创: Hollis Hollis 负载 ... -
(转)对象复用
2018-05-20 15:27 857public class Student { priv ... -
mapreduce中入门中要注意的几点
2018-05-06 08:59 670在 mapreduce中,比如有如下的词: I love b ... -
HDFS的基本操作
2018-05-02 21:47 937-mkdir 在HDFS创建目录 ... -
一个不错的开源工具类,专门用来解析日志头部的,好用
2018-05-02 20:00 768一个不错的开源工具类,专门用来解析日志头部的,好用。 http ... -
介绍个不错的RESTFUL MOCK的工具wiremock
2018-04-27 21:02 1904介绍个不错的RESTFUL MOCK的工具wiremock,地 ...
相关推荐
B站@同济子豪兄python数据分析神器Jupyter notebook快速入门笔记
总之,BTrace作为Java线上调试的神器,为开发者提供了高效的问题排查手段,但同时也需要我们合理、谨慎地运用,确保不影响系统的稳定性和性能。熟悉并掌握BTrace,无疑能提升我们在生产环境中的故障排查能力。
ORACLE 快速入门文档 作为一名 IT 行业大师,我将为您详细解释 Oracle 快速入门文档中的知识点。 首先,让我们从 Oracle 的基本概念开始。Oracle 是美国 Oracle 公司(甲骨文)提供的一组软件产品,以分布式数据库...
3DMAX一键快速生成砖墙插件 安装方法: 解压缩后,直接拖动插件脚本文件到3dmax视口中打开。 主要功能: -偏移以将不同的墙放在一起; -可以按照样条曲线创建墙; -随机化砖块的随机函数; -多个子对象中的随机...
"百度快速秒收录神器"就是这样一款针对网站管理员和SEO专业人士的工具,它旨在帮助用户快速有效地将网站链接提交给百度,以期提升网站的收录速度,从而增加网站的可见性。 这款神器的核心功能主要分为两部分: 1. ...
java线上问题定位神器,Btrace-bin-1.3.10,适用于jdk1.7(+),解压即可使用,一般人我不告诉他。
百度快速收录SEO工具软件 网站快速收录程序【百度秒收录神器】 百度快速收录SEO工具 网站快速收录软件【百度秒收录神器】 里面有百度秒收录的方法和注意事项 软件特色: 1、全新收录通道优化 2、操作界面直观简洁 3...
"ps载入切图神器实现快速切图"这个主题涉及到的是利用Adobe Photoshop(简称PS)中的自动化功能来加速切图过程,这对于前端开发人员和UI设计师来说是一项必备技能。切图神器,通常是指一种自动动作(Action)集合,...
BTrace作为线上问题定位神器,它在侵入、安全、资源占用等方面表现的都非常出色。
总的来说,H3C的标杆神器提供了便捷的FTP服务器搭建方案,使得网络管理员可以快速部署并管理FTP服务,满足文件共享和传输的需求。但需要注意,正确配置和管理FTP服务器是确保网络和数据安全的关键。
【神器海螺网址快速直达】是一个致力于提升网络浏览效率的项目,主要针对JavaScript开发者和对网页导航有高效需求的用户。这个项目的核心是利用JavaScript技术实现快速、便捷地访问常用网址,通过简洁的界面和定制化...
【仿站软件与扒站神器:快速建站的高效途径】 在互联网开发领域,"仿站"是指通过参照已有的网站设计和布局,快速构建出类似功能和视觉效果的新站点。这种做法尤其适用于初创公司或者个人,他们希望快速拥有一个符合...
SEO神器快速排名系统是一种专门针对搜索引擎优化(SEO)设计的技术工具,旨在帮助网站在搜索引擎结果页上获得更高的排名,从而增加网站的可见性、流量和潜在用户。SEO是互联网营销策略的重要组成部分,通过优化网站...
"卸载神器"是一款专为此目的设计的工具,它旨在提供一种高效、简便且彻底的卸载解决方案,帮助用户快速解决软件清理的问题。 首先,我们要理解为什么普通卸载方式可能存在问题。通常,通过Windows的控制面板或应用...
36-03办公神器:快速显示桌面和切换窗口,视频教程
该软件提供了丰富的功能和数据分析工具,使用户能够快速、准确地分析个股表现和市场走势。 通过龙头复盘神器V4.93,用户可以获取实时的股票行情数据、技术指标和图表分析,以及各种交易策略和投资建议。该软件还...
总的来说,"【神器1】快速去掉PDF密码" 是一个实用的工具,可以帮助用户解除PDF文件的访问限制,从而便于编辑、注释和打印。在使用过程中,用户应遵守相关法律法规,保障数据安全,并妥善备份重要文件。
Django还提供了强大的表单处理、用户认证系统和管理后台,可以快速搭建复杂且安全的Web应用。在本资源中,你将看到如何利用Django的MVC设计模式,构建高效的Web服务。 2. Tornado:Tornado是一款轻量级的Web框架和...
下载速度不是一般的快