作者:北京运维

本文档是身边一些朋友、技术大佬之前分享的一些笔记,记录了 Tomcat 优化方法,笔记较多而且比较杂乱,经过整理、分类我个人觉得大致可以从以下几个方面优化 Tomcat:

  1. Tomcat 运行模式
  2. Tomcat 配置优化
  3. JVM 优化
  4. 内核参数优化

一、修改 Tomcat 运行模式

Tomcat Connector有三种运行模式:

  • bio:阻塞 IO bio 是三种运行模式中性能最低第一种。

  • nio:是一个基于缓冲区,并能提供非阻塞 I/O 操作的 JAVA API 因此 NIO 也成为非阻塞 I/O,比 bio 拥有更好的并发性能(默认是 nio)。

  • apr:调用 httpd 核心链接库来读取或文件传输,从而提高 tomcat 对静态文件的处理性能。Tomcat APR 模式也是 Tomcat 在高并发下的首选运行模式。

APR 模式文档链接:http://tomcat.apache.org/tomcat-8.5-doc/apr.html

1.1 安装 apr 和 apr-util

Apache Portable Runtime 是一个高度可移植的库,是 Apache HTTP Server 2.x 的核心。APR 有许多用途,包括访问高级 IO 功能(如sendfile,epoll 和 OpenSSL),操作系统级功能(随机数生成,系统状态等)和本机进程处理(共享内存,NT 管道和 Unix 套接字)。

$ cd /usr/local/src/
$ wget http://mirrors.tuna.tsinghua.edu.cn/apache//apr/apr-1.6.5.tar.gz
$ wget http://mirrors.tuna.tsinghua.edu.cn/apache//apr/apr-util-1.6.1.tar.gz
$ tar xf apr-1.6.5.tar.gz
$ cd apr-1.6.5
$ /configure --prefix=/usr/local/apr
$ make -j 2 && make install
$ cd ../
$ tar xf apr-util-1.6.1.tar.gz
$ cd apr-util-1.6.1
$ ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/

1.2 安装 tomcat-native

tomcat-native 不用单独下载,解压缩 tomcat 程序包后再 bin/ 目录下存在该程序的源码包。

$ tar xf apache-tomcat-8.5.38.tar.gz -C /usr/local/
$ ln -sv /usr/local/apache-tomcat-8.5.38/ /usr/local/tomcat
$ cp /usr/local/tomcat/bin/tomcat-native.tar.gz /usr/local/src/
$ tar xf tomcat-native.tar.gz
$ cd tomcat-native-1.2.21-src/
$ cd native/
$ ./configure --prefix=/usr/local/apr --with-java-home=/usr/local/jdk1.8.0_121/
$ make -j 2 && make install
$ vim /etc/profile
export LD_LIBRARY_PATH=/usr/local/apr/lib ##添加apr path
$ source /etc/profile

1.3 修改 Tomcat 配置文件

1、修改 protocol 值

Tomcat 默认是 "HTTP/1.1" ,如果运行 apr 模式需要把 protocol 值修改成 apr 模式:org.apache.coyote.http11.Http11AprProtocol 参考官方文档中 protocol 说明:http://tomcat.apache.org/tomcat-8.5-doc/config/http.html#HTTP/1.1_and_HTTP/1.0_Support

$ cd /usr/local/tomcat/conf/
$ vim server.xml
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="20000"
redirectPort="8443" />

2、修改 SSLEngine

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" />

1.4 启动 Tomcat 验证

查看 catalina.out 日志中最下面三行

二、Tomcat 配置优化

2.1 增大随机数熵池

你是否遇到过当你执行了 ./startup.sh 或者 ./catalina.sh start 后,访问你的服务会一直转啊转啊,可能要几分钟才能正常提供服务。

原因:

在apache-tomcat 官方文档:如何让 tomcat 启动更快里面提到了一些启动时的优化项,其中一项是关于随机数生成时,采用的 "熵源"(entropy source)的策略。提到 tomcat7 的 session id 的生成主要通过 java.security.SecureRandom 生成随机数来实现,随机数算法使用的是 ”SHA1PRNG” 文章具体内容见下图

http://wiki.apache.org/tomcat/HowTo/FasterStartUp (Entropy Source 部分)有一段解释。stackoverflow 上面也有一大批这方面的说明,所以这里就不再多做介绍。

2.1.1 使用伪随机函数生成器

通过修改 Tomcat 启动文件 -Djava.security.egd=file:/dev/urandom
通过修改 JRE 中的 java.security 文件 securerandom.source=file:/dev/urand

2.1.2 增大/dev/random的熵池(推荐)

安装熵池服务 rngd

$ yum -y install rng-tools
$ systemctl start rngd
$ systemctl enable rngd

启动服务后观察 cat /proc/sys/kernel/random/entropy_avail 基本在三千左右。

2.2 隐藏 Tomcat 版本号

隐藏 Tomcat 版本号,不在优化内容范围内,出于安全角度建议大家隐藏。

修改前如下:

$ cd /usr/local/tomcat/lib/
$ jar xf catalina.jar
$ cd org/apache/catalina/util/
$ vim ServerInfo.properties
# 修改下面信息
server.info=Apache Tomcat/8.5.38
server.number=8.5.38.0
server.built=Feb 5 2019 11:42:42 UTC
修改后为
server.info=Apache Tomcat
server.number=0.0.0.0
server.built=Feb 5 2019 11:42:42 UTC

将修改后的信息压缩回 jar 包:

$ cd  /usr/local/tomcat/lib
$ jar uvf catalina.jar org/apache/catalina/util/ServerInfo.properties
正在添加: org/apache/catalina/util/ServerInfo.properties(输入 = 885) (输出 = 512)(压缩了 42%) # 重启 Tomcat

修改后再查看如下:

2.3 server.xml 配置文件优化

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="40000"
maxHttpHeaderSize="32768"
redirectPort="8443"
maxThreads="1000"
minSpareThreads="100"
maxSpareThreads="1000"
acceptorThreadCount="2"
acceptCount="2000"
minProcessors="100"
maxProcessors="2000"
enableLookups="false"
maxKeepAliveRequests="-1"
keepAliveTimeout="-1"
disableUploadTimeout="false"
connectionUploadTimeout="150000"
useSendfile="false"
URIEncoding="UTF-8" />

配置参数说明

protocol="HTTP/1.1"

maxHttpHeaderSize="8192"

maxThreads="1000" //最大线程数,默认200

minSpareThreads="100" //Tomcat初始化时创建的socket线程数,线程的最小运行数目,这些始终保持运行,如果未指定,默认值为10

enableLookups="false"//关闭DNS反向查询,若设为true,则支持域名解析,可把ip地址解析为主机名

compression="on"//打开压缩功能

compressionMinSize="2048"

compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"

connectionTimeout="20000"//代表连接超时时间,单位为毫秒,默认值为60000。通常情况下设置为30000

URIEncoding="utf-8"//URL统一编码

acceptCount="1000"//监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads),如果未指定,默认值为100

redirectPort="8443"//在需要基于安全通道的场合,把客户请求转发到基于SSL的redirectPort端口

disableUploadTimeout="true"/>//这个标志允许servlet[Container](http://lib.csdn.net/base/4)在一个servlet执行的时候,使用一个不同的,更长的连接超时。最终的结果是给servlet更长的时间以便完成其执行,或者在数据上载的时候更长的超时时间。如果没有指定,设为false

禁用 AJP(如果你服务器没有使用 Apache)

<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->

Tomcat 压缩配置,建议在前端 nginx 上开启压缩。Tomcat 作为应用服务器本身就很繁忙了。

compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,application/javascript,application/json,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png"

三、JVM 优化

Java 程序调优,主要就是调『堆内存』和『垃圾回收机制』。

3.1 JVM 调优常用参数说明

参数 作用
-Xms 堆初始内存大小
-Xmx 堆最大内存大小
-Xmn 初始新生代内存大小,一般设置为整个堆的 1/3到 1/4 左右
-XX:PrintGC 每次触发GC的时候打印相关日志
-XX:+PrintGCDetails 更详细的GC日志
-XX:SurvivorRatio=2 用来设置新生代中 Eden 空间和 from/to 空间比例,默认是 8 (Edem : from : to = 8 : 1 : 1)
-Dfile.encoding=UTF-8 设置字符集避免日志中出现乱码
-Dsun.jnu.encoding=UTF-8 设置字符集避免日志中出现乱码
-Duser.timezone=GMT+08 时区设置
-XX:+HeapDumpOnOutOfMemoryError 堆异常报错输出
-XX:HeapDumpPath=path 设置在dump heap时将文件dump到哪里。默认是当前目录下 java_pidpid.hprof这样形式的文件。
-XX:+UseParallelGC 选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集
-XX:+UseParallelOldGC 配置年老代垃圾收集方式为并行收集。
-XX:ParallelGCThreads=8 设置支持并发GC的线程数。

3.2 调优总结

在实际工作中,我们可以直接将初始堆大小(-Xms)与最大堆大小(-Xmx) 配置相等,这样的好处就是可以减少程序运行时垃圾回收的次数,从而提高效率。

新生代与老年代的设置比例:1:3 或者 1:4

四、内核参数优化

以下内核参数是工作环境中大家经常会看到的一些:

net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 65535

以上内核参数作用说明:

# cat /proc/sys/net/core/netdev_max_backlog
# 默认值:1000
# 作用:网卡设备将请求放入队列的长度
net.core.netdev_max_backlog = 32768 # cat /proc/sys/net/core/somaxconn
# 默认值:128
# 作用:已经成功建立连接的套接字将要进入队列的长度
net.core.somaxconn = 32768 # cat /proc/sys/net/core/rmem_default
# 默认值:212992
# 作用:默认的TCP数据接收窗口大小(字节)
net.core.rmem_default = 8388608 # cat /proc/sys/net/core/wmem_default
# 默认值:212992
# 作用:默认的TCP数据发送窗口大小(字节)
net.core.wmem_default = 8388608 # cat /proc/sys/net/core/rmem_max
# 默认值:212992
# 作用:最大的TCP数据接收窗口大小(字节)
net.core.rmem_max = 16777216 # cat /proc/sys/net/core/wmem_max
# 默认值:212992
# 作用:最大的TCP数据发送窗口大小(字节)
net.core.wmem_max = 16777216 # cat /proc/sys/net/ipv4/ip_local_port_range
# 默认值:32768 61000
# 作用:可用端口的范围
net.ipv4.ip_local_port_range = 1024 65535 # cat /proc/sys/net/ipv4/route/gc_timeout
# 默认值 300
# 作用:路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由
net.ipv4.route.gc_timeout = 100 # cat /proc/sys/net/ipv4/tcp_fin_timeout
# 默认 60
# 作用:表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
net.ipv4.tcp_fin_timeout = 30 # cat /proc/sys/net/ipv4/tcp_keepalive_time
# 默认值:7200
# 作用:间隔多久发送1次keepalive探测包
net.ipv4.tcp_keepalive_time = 1200 # cat /proc/sys/net/ipv4/tcp_timestamps
# 默认值:1
# 作用:TCP时间戳,时间戳必须要开启,否则下面的 TIME_WAIT 重用和快速回收无效
net.ipv4.tcp_timestamps = 1 # cat /proc/sys/net/ipv4/tcp_tw_recycle
# 默认值:0
# 作用:表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_tw_recycle = 1 ######################## cat /proc/sys/net/ipv4/tcp_tw_reuse
# 默认值:0
# 作用:针对 TIME-WAIT,做为客户端可以启用(例如,作为nginx-proxy前端代理,要访问后端的服务)
net.ipv4.tcp_tw_reuse = 1 # cat /proc/sys/net/ipv4/tcp_syn_retries
# 默认值 2
# 作用:在内核放弃建立连接之前发送SYN包的数量。
net.ipv4.tcp_syn_retries = 1 # cat /proc/sys/net/ipv4/tcp_synack_retries
# 默认值 2
# 作用:为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。
net.ipv4.tcp_synack_retries = 1 # cat /proc/sys/net/ipv4/tcp_mem
#确定 TCP 栈应该如何反映内存使用;每个值的单位都是内存页(通常是 4KB)。
#第一个值是内存使用的下限。
#第二个值是内存压力模式开始对缓冲区使用应用压力的上限。
#第三个值是内存上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的 BDP 可以增大这些值(但是要记住,其单位是内存页,而不是字节)。
net.ipv4.tcp_mem = 94500000 915000000 927000000 # cat /proc/sys/net/ipv4/tcp_max_orphans
# 默认值 16384
# 作用:系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单 的DoS攻击,你绝对不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
net.ipv4.tcp_max_orphans = 3276800 # cat /proc/sys/net/ipv4/tcp_max_syn_backlog
# 默认值:128
# 作用:增大SYN队列的长度,容纳更多连接
net.ipv4.tcp_max_syn_backlog = 65535

五、JVM 调优常用工具

5.1 为 Tomcat 配置 JMX 连接

开启 JMX 远程连接以后,就可以通过 jconsolejvisualvm 两个 JDK 内置工具连接 JMX 从而查看当前主机的 JVM 相关信息。

$ cd /usr/local/tomcat/bin/
# 默认情况下,$CATALINA_HOME/bin 目录下是没有 setenv.sh,可以自己新建此文件
$ vim setenv.sh
CATALINA_OPTS="-Djava.rmi.server.hostname=10.100.4.169
-Dcom.sun.management.jmxremote.port=8686
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false"
:wq

JMX 配置说明:

# 通过哪个 IP 访问本机的 JMX
-Djava.rmi.server.hostname=10.100.4.169
# JMX 监听的端口,默认 8686
-Dcom.sun.management.jmxremote.port=8686
# 是否需要用户名密码认证,默认 false
-Dcom.sun.management.jmxremote.authenticate=false
# 是否启用 SSL
-Dcom.sun.management.jmxremote.ssl=false"

5.2 使用 jconsole 工具连接 JMX

Jconsole 是 JDK 自带的监控工具,在 JDK/bin 目录下可以找到。它用于连接正在运行的本地或者远程的 JVM,对运行在 java 应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。

当你在 Windows 或者 Mac 下运行 jconsole 后就会在桌面弹出 jconsole 的控制台,选择远程连接,输入IP:端口 点击连接

我这里在配置 JMX 的时候没有启用 SSL 所以会提示不安全,点击『不安全的连接』

5.3 使用 jvisualvm 工具连接 JMX

jvisualvm 同样是 JDK 内置的工具,使用方法与 jconsole 类似。功能上要比 jconsole 强大一些。推荐使用。

运行 jvisualvm 后同样在桌面弹出一个控制台窗口

远程 --> 添加主机 --> 添加 JMX 连接

5.4 jmap 工具

jmap 可以输出 Java 进程 内存中对象的工具。jmap 一般和 jhat 或者 MAT 配合使用,以图像的形式直观的展示当前内存是否有问题。

5.4.1 参数说明

-dump:[live,]format=b,file=<filename>
以hprof二进制格式转储Java堆到指定filename的文件中。
live子选项是可选的,如果指定了live子选项,堆中只有活动的对象会被转储。
想要浏览heap dump,你可以使用 jhat(Java堆分析工具) 或者 MAT 读取生成的文件。 -finalizerinfo
打印等待终结的对象信息。 -heap
打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和generation wise heap usage。 -histo[:live]
打印每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。
打印的虚拟机内部的类名称将会带有一个'*'前缀。
如果指定了live子选项,则只计算活动的对象。 -permstat
打印Java堆内存的永久保存区域的类加载器的智能统计信息。
对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。
此外,包含的字符串数量和大小也会被打印。 -F
强制模式。如果指定的pid没有响应,请使用jmap -dump或jmap -histo选项。此模式下,不支持live子选项。 -h | -help
打印帮助信息。 -J<flag>
指定传递给运行jmap的JVM的参数。

5.4.2 例子

示例 1、jmap -histo <pid> 打印每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。

$ jmap -histo 14110

 num     #instances         #bytes  class name
----------------------------------------------
1: 50994 7789848 [C
2: 22160 6263680 [B
3: 8527 1437176 [I
4: 49099 1178376 java.lang.String
5: 63 936248 [J
6: 19118 611776 java.util.HashMap$Node
7: 6243 549384 java.lang.reflect.Method
8: 8948 509464 [Ljava.lang.Object;
9: 10588 423520 java.util.TreeMap$Entry
10: 3696 417952 java.lang.Class
11: 1372 230544 [Ljava.util.HashMap$Node;
12: 4760 228480 java.util.HashMap
13: 4789 191560 java.util.HashMap$ValueIterator
14: 5851 187232 java.io.File

B byte

C char

D double

F float

I int

J long

Z boolean

[ 数组,如[I表示int[]

[L+类名 其他对象

示例 2、jmap -heap <pid> 查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。

$ jmap -heap 14110

Attaching to process ID 14110, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13 using thread-local object allocation.
Parallel GC with 2 thread(s) Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 134217728 (128.0MB)
NewSize = 44564480 (42.5MB)
MaxNewSize = 44564480 (42.5MB)
OldSize = 89653248 (85.5MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB) Heap Usage:
PS Young Generation
Eden Space:
capacity = 19398656 (18.5MB)
used = 6316256 (6.023651123046875MB)
free = 13082400 (12.476348876953125MB)
32.56027634079392% used
From Space:
capacity = 12582912 (12.0MB)
used = 98304 (0.09375MB)
free = 12484608 (11.90625MB)
0.78125% used
To Space:
capacity = 12582912 (12.0MB)
used = 0 (0.0MB)
free = 12582912 (12.0MB)
0.0% used
PS Old Generation
capacity = 89653248 (85.5MB)
used = 20189088 (19.253814697265625MB)
free = 69464160 (66.24618530273438MB)
22.519081517269736% used 13984 interned Strings occupying 1890552 bytes.

示例 3、jmap -dump:format=b,file=<dumpFileName> <pid> 用jmap把进程内存使用情况dump到文件中

$ jmap -dump:format=b,file=/tmp/123.hprof 14110
Dumping heap to /tmp/123.hprof ...
Heap dump file created

5.5 jhat 工具

jhat 可以对 dump 出来的堆信息进行处理,以 html 页面的形式展示出来。

执行 jhat /tmp/123.hprof即可,默认端口是 7000,访问 http://localhost:7000 即可查看结果。通过 -port 指定端口。

以上就是我整理出的 Tomcat 基础优化方法,如果有不对的地方或者你有更好的建议,欢迎在评论区留言,谢谢。

Tomcat 基础优化的更多相关文章

  1. Tomcat性能优化(转载)

    出处:微信订阅号GitChat精品课程 — Tomcat性能优化 Tomcat 简单介绍 Sun 公司创建了第一个 Servlet 容器,即 Java Web Server,但 JWS 只是为了演示 ...

  2. Tomcat并发优化和缓存优化

    Tomcat并发优化 1.调整连接器connector的并发处理能力 在Tomcat 配置文件 server.xml 中的 <Connector ... /> 配置中 1.参数说明 max ...

  3. Tomcat调优总结(Tomcat自身优化、Linux内核优化、JVM优化)

    Tomcat自身的调优是针对conf/server.xml中的几个参数的调优设置.首先是对这几个参数的含义要有深刻而清楚的理解.以tomcat8.5为例,讲解参数. 同时也得认识到一点,tomcat调 ...

  4. Tomcat 7优化配置

    Tomcat 的优化不像其它软件那样,简简单单的修改几个参数就可以了,它的优化主要有三方面,分为系统优化,Tomcat 本身的优化,Java 虚拟机(JVM)调优.系统优化就不在介绍了,接下来就详细的 ...

  5. Tomcat基础配置和高级配置

    **********  第一部分 Tomcat基础配置   *********** 一.Apatch Tomcat 在win下配置 大部分转载自:http://blog.csdn.net/liuhao ...

  6. tomcat性能优化参数

    线上环境使用默认tomcat配置文件,性能很一般,为了满足大量用户的访问,需要对tomcat进行参数性能优化,具体优化的地方如下: Linux内核的优化 服务器资源JVM 配置的优化 Tomcat参数 ...

  7. Linux实战教学笔记06:Linux系统基础优化

    第六节 Linux系统基础优化 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 基础环境 第2章 使用网易163镜像做yum源 默认国外的yum源速度很慢,所以换成国内的. 第一步:先备份 ...

  8. tomcat 性能优化

    tomcat 性能优化tomcat默认参数是为开发环境制定,而非适合生产环境,尤其是内存和线程的配置,默认都很低,容易成为性能瓶颈. tomcat内存优化linux修改TOMCAT_HOME/bin/ ...

  9. Tomcat的优化

    Tomcat的优化配置 修改tomcat的config目录下server.xml文件 <Connector port="9021"  protocol="HTTP/ ...

随机推荐

  1. 部署MVC项目ManagedPipelineHandler报错

    "处理程序ExtensionlessUrlHandler-Integrated-4.0在其模块列表中有一个错误模块ManagedPipelineHandler": 解决方法:以管理 ...

  2. PHPStorm 忽略 node_modules 目录

    如果项目中包含 node_modules 目录,会使 PHPStorm 卡得很慢, 原因:PHPStorm 在进行大量的扫描工作. 解决:忽略它 原文地址:https://segmentfault.c ...

  3. 模拟在table中移动鼠标,高亮显示鼠标所在行,固定表头

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  4. RabbitMQ的一些说明

    下载安装包后,运行会提示你下再ErLang环境,根据提示下载安装就可以了 RabbitMQ 自己的插件包中带一 个WebUI的管理工具,在RabbitMQ安装目录(bin)下运行 rabbitmq-p ...

  5. UVa 1153 Keep the Customer Satisfied (贪心+优先队列)

    题意:给定 n 个工作,已知每个工作要用的时间 q 和 截止时间 d,问你最多完成多少个工作,每次最多能运行一个工作. 析:这个题是贪心,应该能看出来,关键是贪心策略是什么,这样想,先按截止时间排序, ...

  6. 加载 bean.xml 的几种方式 (java or web project)

    1. java project ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:bean1.xm ...

  7. SpringMVC源码解读 - HandlerMapping

    SpringMVC在请求到handler处理器的分发这步是通过HandlerMapping模块解决的.handlerMapping 还处理拦截器. 先看看HandlerMapping的继承树吧 可以大 ...

  8. 20155308 2016-2017-2 《Java程序设计》第8周学习总结

    20155308 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章 NIO与NIO2 NIO(New IO)-from JDK1.4 NIO2 -fr ...

  9. int *a[] 与(int *)a【5】的区别

    *a[5] 是指针数组  可以指向5个值 (*a)[5]  是一个指针,但这个指针只能指向包含5个元素的一维数组 a是一个数组,每个元素都是个指针. b是一个指针,指向一个数组 1.int *a[5] ...

  10. 一个hql语句

    在hql语句里面,in的使用方法比较特别. from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' ) in后面是一个list,我写的 ...