Apache-tomcat

总体说明

官网:http://tomcat.apache.org/

版本:7.0.x

tomcat目录结构及管件文件

Apache-Tomcat
|
+-- bin    --存放tomcat在window或linux平台下操作的脚本文件
+  |
+  +-- startup.sh    --tomcat在linux下的启动脚本
+  +-- startup.bat    --tomcat在windows下的启动脚本
+  +-- version.sh    --tomcat在linux下的查看版本脚本
+  +-- version.bat    --tomcat在windows下的查看版本脚本
+  +-- shutdown.sh    --tomcat在linux下的关闭脚本
+  +-- shutdown.bat    --tomcat在windows下的关闭脚本
+  +-- ……
+-- conf    --存放tomcat所有的配置文件
+  |
+  +-- Catalina
+  +-- |
+  +-- +-- localhost    --通过配置的放置进行部署
+  +-- server.xml    --tomcat的主要配置文件
+  +-- web.xml    --默认web应用使用到的配置,子项目将会继承于此
+  +-- ……
+-- lib    --存放tomcat所需要的以及作用于全局的jar
+-- logs    --存放日志文件
+-- temp    --临时目录
+-- webapps    --应用程序部署目录
+-- work    --存放JSP文件的转译和编译文件目录
+-- LICENSE
+-- NOTICE
+-- RELEASE-NOTES
+-- RUNNING.TXT

tomcat的类的优先级顺序

  1.  webprj/WEB-INF/classes/*.class
  2. webprj/WEB-INF/lib/*.jar
  3. BootStrap($JAVA_HOME/jre/lib/ext/*.jar)
  4. System($CLASSPATH/*.jar 或 *.class)
  5. $CATALINA_HOME/lib/*.jar

在tomcat部署的应用程序中,放置在webprj/WEB-INF/classes/*.class文件最优先被使用。

技巧:当我们需要覆盖第三方或其他商业jar中的class文件时,可以通过在这个目录中建立相同包名.类名的class进行覆盖。

conf/server.xml的说明

典型tomcat中server.xml配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<? xml  version = '1.0'  encoding = 'utf-8' ?>
< Server  port = "8005"  shutdown = "SHUTDOWN" >
     < Listener  className = "org.apache.catalina.startup.VersionLoggerListener"  />
     < Listener  className = "org.apache.catalina.core.AprLifecycleListener"  SSLEngine = "on"  />
     < Listener  className = "org.apache.catalina.core.JasperListener"  />
     < Listener  className = "org.apache.catalina.core.JreMemoryLeakPreventionListener"  />
     < Listener  className = "org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"  />
     < Listener  className = "org.apache.catalina.core.ThreadLocalLeakPreventionListener"  />
     
     < GlobalNamingResources >
         < Environment  name = "maxExemptions"  value = "10"  type = "java.lang.Integer"  override = "false"  />
           
         < Resource  auth = "Container"  factory = "com.alibaba.druid.pool.DruidDataSourceFactory"
             name = "DefaultDataSource"  username = "dbuser"  password = "******"  maxActive = "10"  maxIdle = "2"
             maxWait = "5000"  type = "javax.sql.DataSource"  url = "dbconnecturl"  />
     </ GlobalNamingResources >
     
     < Service  name = "Catalina" >
         < Executor  name = "tomcatThreadPool"  namePrefix = "catalina-exec-"
             maxThreads = "150"  minSpareThreads = "4"  />
             
         < Connector  port = "8080"  protocol = "HTTP/1.1"
             connectionTimeout = "20000"  redirectPort = "8443"  />
             
         < Connector  port = "8009"  protocol = "AJP/1.3"  redirectPort = "8443"  />
         
         < Engine  name = "Catalina"  defaultHost = "localhost" >
             < Realm  className = "org.apache.catalina.realm.LockOutRealm" >
                 < Realm  className = "org.apache.catalina.realm.UserDatabaseRealm"  resourceName = "UserDatabase"  />
             </ Realm >
             
             < Host  name = "localhost"  appBase = "webapps"  unpackWARs = "true"  autoDeploy = "true" >
                 < Valve  className = "org.apache.catalina.valves.AccessLogValve"
                     directory = "logs"  prefix = "localhost_access_log."  suffix = ".txt"
                     pattern = "%h %l %u %t &quot;%r&quot; %s %b"  />
             </ Host >
         </ Engine >
     </ Service >
</ Server >
Server节点:
Server节点表示整个Tomcat Servlet容器,此节点是Server.xml的根节点,用于描述整个Tomcat Servlet容器的特点。属性描述:
属性名称
必须
默认取值
描述
classNametomcat标准实现指定Server实现java类的全限定名,此类必须实现org.apache.catalina.Server接口。tomcat标准实现:org.apache.catalina.core.StandardServer
addresslocalhost指定连接端口的IP地址。

port

8005指定关闭tomcat的监听端口,该端口不能被其他进程所占用。关闭该端口,可以设置为“-1”,则不能通过shutdown.sh/shutdiwn.bat的方式停止tomcat。 
shutdownSHUTDOWN指定关闭tomcat的关闭命令,严格区分大小写。
Listener节点:

用于处理Tomcat Server启动或停止时特定的一些动作处理。Listener节点可以作为Server、Engine、Context、Host子节点存在,作用在子节点时相关的约束在将限制在子节点内。以下列举tomcat自带的几个Listener进行说明。

  • org.apache.catalina.startup.VersionLoggerListener

说明:作用是Tomcat Server在启动时输出的基本信息,信息包含Tomcat Server、Java、System,在catalina.out中会看到。此Listener只能用在Server节点下,并且放在Listener的首个。属性描述:

属性名称
必须
默认取值
描述
logArgstrue如果设定为true,将会在日志中输出启动脚本中的参数。
logEnvfalse如果设定为true,将会在日志中输出当前的环境变量。
  • org.apache.catalina.core.AprLifecycleListener

说明:Tomcat Server在启动过程中检测APR的本地库和加载库是否存在。此Listener只能用在Server节点下。属性描述:

 

属性名称
必须
默认取值
描述
SSLEngineon

on:开启SSL,将使用本地的SSL Engine

off:不使用SSL

SSLRandomSeedbuiltin
FIPSModeoff

FIPSMode依赖于用户自己建立的OpenSSL库,如果取值不是off,必须要保证SSLEngine已经正常启动。

on:需要设置OpenSSL设置为FIPS模式

enter:强制设置OpenSSL使用FIPS模式,如果OpenSSL已经是FIPS模式,将会发生错误。

require:需要设置OpenSSL为FIPS模式,如果OpenSSL不是FIPS模式,将会发生错误。

off:?

 

  • org.apache.catalina.core.JasperListener

说明:Tomcat Server在加载所有Web Application之前必须要先对JSP的引擎通过此Listener进行初始化。此Listener只能用在Server节点下。

  • org.apache.catalina.core.JreMemoryLeakPreventionListener

说明:会随着Tomcat Server启动对类加载器监控是否发生内存泄露的状况。

属性名称
必须
默认取值
描述
appContextProtection

true <= jdk1.6

false >= jdk1.7

保护应用程序不会发生内存泄露,但这将会导致应用程序中的部分内容停止运行。
AWTThreadProtectionfalse
classesToInitialize  
driverManagerProtection  
gcDaemonProtection  
java2DDisposerProtection  
ldapPoolProtection  
securityLoginConfigurationProtection  
securityPolicyProtection  
tokenPollerProtection  
urlCacheProtection  
xmlParsingProtection  

 

  • org.apache.catalina.mbeans.GlobalResourcesLifecycleListener

说明:配置Tomcat Server在启动过程中可以识别GlobalNamingResources里面配置的数据源。此LISTENER只能作用在Server节点下。

  • org.apache.catalina.core.ThreadLocalLeakPreventionListener

说明:

GlobalNamingResources节点:

用于配置Tomcat Server全局的JNDI数据源。

Environment节点:

用户配置Tomcat Server全局的变量。

属性名称
必须
默认取值
描述
description环境变量的描述说明
name环境变量的名称,
overridetrue是否允许被同名的环境变量所覆盖。
type环境变量数据的类型,类的全限定名。
value环境变量的取值

 

Resource节点:

配置JNDI数据源。

属性名称
必须
默认取值
描述
auth

Application:

Container:

closeMethod在单例资源的情况下,当资源不再被使用时将会触发closeMethod进行资源释放。非单例资源的情况下,此参数将被忽略。
description

JNDI资源的描述。

nameJNDI资源的名称。
scopeShareable

Shareable:

Unshareable:

singletontrue此资源是否为单例类型。如果为true,每次通过JNDI查找到的结果将会是同一个实例,如果为false每次返回的将是不同的实例。如果是javax.sql.DataSource类型的资源,此处必须使用true。
typeWeb应用程序中,通过JNDI查找此资源时使用的JavaClass的全限定名。
ResourceLink节点:

将一个全局的JNDI资源引入到一个WEB项目中。

Transaction节点:

Service节点:

Service节点由至少一个Connector和一个Engine节点组成,用来处理Connector节点上接收到的请求。可以由多个Service节点在Server节点内。

属性名称
必须
默认取值
描述
className

tomcat的标准实现

org.apache.catalina.core.StandardService

service的实现类的全限定名,必须实现org.apache.catalina.Service接口。如果该属性没有特殊指定,将会使用tomcat标准实现。
nameservice的名称,在tomcat标准实现中会在日志中输出。如果配置多个service节点,此名称要保证唯一性。·

 

Executor节点:

可以建立统一公共的线程池,供多个Connector使用。

属性名称
必须
默认取值
描述
className

tomcat标准实现

org.apache.catalina.core.StandardThreadExecutor

创建Executor线程池Java类的全限定名,此类必须要实现org.apache.catalina.Executor接口。
name线程池的引用名称,此名称必须是唯一的。

使用Tomcat标准实现(org.apache.catalina.core.StandardThreadExecutor)的其他属性

属性名称
必须
默认取值
描述
threadPriority5描述当前线程的优先级。
daemontrue描述是否为守护线程。
namePrefix 线程名称前缀。线程名称命名规则:namePrefix+threadNumber
maxThreads200线程池中最大的活动线程数。
minSpareThreads25线程池中最下的空闲线程数。
maxIdleTime60000毫秒线程空闲时常,当线程中中线程超过minSpareThreads的数量,且空闲时长达到maxIdleTime后,线程池将会销毁此线程。
maxQueueSizeInteger.MAX_VALUE当线程池中没有空闲处理线程,请求将会暂存在此队列中,等待空闲线程处理。
prestartminSpareThreads

falser

tomcat启动后是否按照minSpareThreads指定的数量创建最小线程数。
threadRenewalDelay1000
Connector节点:

Tomcat Server提供了2个类别的Connector的不同实现,分别是Http Connector和AJP Connector,下面将针对两种Connector进行分别说明。

Http Connector

HTTP Connector代表了支持HTTP/1.1协议的Connector组件,使Tomcat Server成为一个能够执行servlet和JSP页面的独立的Web服务器。一个HTTP Connector组件的实例监听服务器上一个特定的TCP端口号上的连接。一个或多个这样的连接器可以配置成一个单一Service的一部分,每个转发到相关联的Engine 处理请求,并创建响应。如果你要配置的Connector,用于连接到Web服务器(Apache Web Server)使用的的AJP协议。

通用配置属性:

属性名称
必须
默认取值
描述
allowTrace false指定是否开启TRACE HTTP method。
asyncTimeout 10000异步请求的超时时间设置,单位:毫秒。
enableLookups false

主要是对request.getRemoteHost()方法产生影响,是否通过DNS查找主机名。

true:通过DNS查找该地址的主机名。

false:直接返回发起请求的主机IP地址。

maxHeaderCount 100限定一个请求头中允许携带header的数量,超过该数量的请求将会被拒绝。如果设定为负数,表示不限制。
maxParameterCount 10000限制GET加POST请求发送参数的数量,超过该数量的请求参数将会被丢弃。如果设定为负数,表示不限制。
maxPostSize 2097152限制在POST时,可以通过URL传递参数的数据量。单位:字节。
maxSavePostSize   4096

将被容器在FORM或CLIENT-CERT认证中保存/缓冲的POST的最大尺寸。单位:字节。

parseBodyMethods post以逗号分隔的HTTP方法列表,通过方法列表,等同于POST方法,request 正文将被解析成请求参数。在这里为了符合HTTP规范明确禁止HTTP方法TRACE。
port启动监听的端口号。如果设置为0,Tomcat将会随机产生一个空闲的端口提供服务。
protocol HTTP/1.1

Tomcat Server处理请求的方式

org.apache.coyote.http11.Http11Protocol:阻塞的Java连接器(bio)。

org.apache.coyote.http11.Http11NioProtocol:非阻塞的Java连接器(nio)。

org.apache.coyote.http11.Http11AprProtocol:APR/Native连接器(apr)。

proxyName 
proxyPort 
redirectPort 如果该Connector支持SSL请求,并且该请求是SSL请求,Tomcat Server会将该请求转向到此处指定的端口号。
scheme HTTP设定request.getScheme()获取到的协议名称。
secure false
URIEncoding ISO-8859-1指定URI字符集编码。
useBodyEncodingForURI false是否使用URI字符集编码对queryString进行转码。
useIPVHosts false
xpoweredBy false

tomcat标准实现配置属性:

属性名称
必填
默认取值
描述
acceptCount100当没有空闲工作线程来处理请求时,请求将会进行暂存排队。允许最大的排队数量,超出改数量后,服务器将会拒绝请求。
acceptorThreadCount1用于接受连接的线程数量。在一个多CPU的机器上可以增加该值。
acceptorThreadPriority5接受连接线程的优先级。
address*监听端口绑定的IP地址。默认情况是绑定所有IP地址。
bindOnInittrue
compressableMimeType

text/html,text/xml,text/plain

可用于压缩的MIME类型列表,多个取值的时候,使用英文半角逗号分隔。
compressionoff是否开启HTTP/1.1的GZIP压缩协议。on:允许压缩,将对文本类型进行压缩;force:强制压缩,将对所有类型进行压缩。
compressionMinSize2048在compression为on的情况下,指定压缩后输出的最小值
connectionLinger-1socket连接空闲时长,单位:秒。-1表示关闭socket空闲时长。
connectionTimeout60000请求连接的超时时长,单位:毫秒。-1:没有限制。
connectionUploadTimeout 上传数据过程中的超时时长设置,单位:毫秒。此属性只有在disableUploadTimeout=false的情况下有效。
disableUploadTimeouttrue是否限制上传数据过程中的超时时长。取值为false时,需要设置connectionUploadTimeout的取值。
executor 指定引用的executor。如果被指定,此节点上所有相关线程的设置都将被忽略,而直接使用被指定executor线程池提供的线程。
executorTerminationTimeoutMillis  
keepAliveTimeout 连接器在关闭之前,将等待HTTP请求的毫秒数,默认使用connectionTimeout的取值。-1标识没有限制。
maxConnections 连接器在同一时刻所能接受的最大连接数。达到此值后连接器不再接受任何连接。BIO默认使用的是maxThread取值;NIO默认取值是10000;APR的默认取值是8192。-1标识不限制最大连接数。
maxExtensionSize  
maxHttpHeaderSize8388608Http包中头信息的大小,单位:字节。默认是8192KB。
maxKeepAliveRequests100一个连接中允许最大处理请求的个数。1:将会禁用长连接;-1:表示不限制;
maxSwallowSize  
maxThreads200用于处理请求的最大线程数。
maxTrailerSize8192
minSpareThreads10最小空闲线程数。
noCompressionUserAgents 
processorCache200

可以缓存的processor对象个数。-1:没有限制。

restrictedUserAgents  
serverApache-Coyote/1.1Http响应头中Servet字段的取值信息。
socketBuffer9000套接字缓冲区大小,单位:字节。-1:没有缓冲区。
SSLEnabledfalse此连接器是否使用SSL连接器传输数据。
tcpNoDelaytrue如果设置为true,TCP_NO_DELAY选项将被设置在服务器上的套接字上,在大多数情况下,这样可以提高性能。
threadPriority5线程优先级。
upgradeAsyncWriteBufferSize  

TCP Socket连接属性配置,在BIO和NIO模式下支持配置:

属性名称
必须
默认值
描述
socket.rxBufSizeJVM设置Socket接收缓冲区(SO_RCVBUF),以字节为单位。
socket.txBufSizeJVM设置Socket发送缓冲区(SO_SNDBUF),以字节为单位。
socket.tcpNoDelayJVM设置相当于Socket的标准属性tcpNoDelay,boolean类型取值
socket.soKeepAliveJVM设置Socket长连接设置(SO_KEEPALIVE),取值:boolean类型
socket.ooBInlineJVM设置

Socket OOBINLINE设置,取值:boolean类型

socket.soReuseAddressJVM设置Socket复用连接地址(SORESUEADDR),取值:boolean类型
socket.soLingerOnJVM设置Socket延时关闭选项,标准属性中connectionLinger>=0时,此值为true,connectionLinger<0时,此值为false。取值为true时,必须设置socket.soLingerTime,否则将使用JVM设置。取值:boolean类型
socket.soLingerTimeJVM设置Socket延时关闭时长(SO_LINGER),单位:秒。
socket.soTimeout 相当于标准属性中的connectionTimeout
socket.performanceConnectionTimeJVM设置性能设置的第一个值,这三个值必须同时设置。
socket.performanceLatencyJVM设置性能设置的第二个值,这三个值必须同时设置。
socket.performanceBandwidthJVM设置性能设置的第三个值,这三个值必须同时设置。
socket.unlockTimeout250Socket解锁的超时时间,单位:毫秒。

BIO的特殊配置项

属性名称
必须
默认值
描述
disableKeepAlivePercentage75长连接失效之前被使用的处理线程的百分比,取值:0=<num<=100

NIO的特殊配置

属性名称
必须
默认值
描述
pollerThreadCount1处理轮询事件的线程数量,在版本7.0.27及以前版本,默认值是每个处理器1个。版本7.0.28的默认值是每个处理器1个,但不超过2个。
pollerThreadPriority5轮询线程的优先级。
selectorTimeout1000选择轮询器的超时时间。单位:毫秒。
useComettrue是否允许comet servlet。comet是基于http的长连接技术。
useSendfiletrue是否允许send file。
socket.directBufferfalse直接使用ByteBuffers或java映射的ByteBuffers。当使用direct ByteBuffers,请确保你分配适当的内存量给直接内存空间。JDK配置如-XX:MaxDirectMemorySize=256M。
socket.appReadBufSize8192在Tomcat中每个连接的开辟连接一个读ByteBuffer。此属性控制这个缓冲区的大小。单位:字节。对于较低的并发,可以增加这个值以缓冲更多的数据。对于长连接数很多的情况,需要降低这个数值或者增加堆大小。
socket.appWriteBufSize8192在Tomcat中每个连接的开辟连接一个写ByteBuffer。此属性控制这个缓冲区的大小。单位:字节。对于较低的并发,你可以增加这个值以缓冲更多的响应数据。对于长连接数很多的情况,你需要降低这个数值或者增加堆大小。
socket.bufferPool500NIO连接器使用NioChannel这个类来持有链接到一个套接字的元素。为了减少垃圾收集,NIO连接器缓存这些通道的对象。此值指定这个缓存的大小。默认值是500,表示缓存将持有500个 NioChannel的对象。-1表示不限制缓存大小,0表示不缓存。
socket.bufferPoolSize1024*1024*100NioChannel池是基于尺寸大小,而不是基于对象数的。NioChannel的缓冲区大小=读取缓冲区大小+写入缓冲区大小;SecureNioChannel的缓冲区大小=应用程序读取缓冲区大小+应用程序写入缓冲区的大小+网络读取缓冲区大小+网络写入缓冲区的大小。单位:字节。
socket.processorCache500Tomcat缓存SocketProcessor对象的最大值。默认值是500。-1表示不限制缓存大小,0表示不缓存。
socket.keyCache500Tomcat缓存KeyAttachment对象的最大值。默认值是500。-1表示不限制缓存大小,0表示不缓存。
socket.eventCache500Tomcat缓存PollerEvent对象的最大值。默认值是500。-1表示不限制缓存大小,0表示不缓存。
selectorPool.maxSelectors200以减少选择器的争用,在池中使用的选择器最大个数。命令行值org.apache.tomcat.util.net.NioSelectorShared设置为false时,使用此选项。
selectorPool.maxSpareSelectors-1以减少选择器的争用,在池中使用的最大备用选择器个数。当选择器返回到池中时,系统可以决定保留它或者让他垃圾回收。当org.apache.tomcat.util.net.NioSelectorShared 值设置为false时,使用此选项。默认值是-1(无限制)
command-line-options 可用于NIO连接器的命令行选项。如果你想每个线程使用一个选择器,将此值设置为false。当你将它设置为false,你可以通过使用selectorPool.maxSelectors属性控制选择器池的大小。
oomParachute1024*1024*1NIO连接器实现了一个名叫parachute的OutOfMemoryError错误的策略。它拥有一个块的数据作为一个字节数组。在一个OOM的情况下,这个数据块被释放,并报告错误。单位:字节。

APR的特殊配置

属性名称
必须
默认值
描述
deferAccept Socket连接上设置TCP_DEFER_ACCEPT标志。操作系统支持TCP_DEFER_ACCEPT时为true,否则为false
pollerSize8192在一个给定的时间内,负责长连接轮询的轮询器能够持有的线程数。额外的连接将被马上关闭。默认值是8192,与8192个长连接数一致。
pollTime 1000*1000

轮询调用持续的时间(以微秒为单位)。在某些情况下,降低该值将略微减少潜在的连接数,但随着增加的轮询调用会使用更多的CPU。默认值是2000(毫秒)。

sendfileSize

1024

 

threadPriority5接收器和轮询器线程的优先级。
useComettrue允许或禁止Comet servlet
useSendfiletrue使用此属性来启用或禁用sendfile的能力

 

AJP Connector

AJP Connector主要使用在通过Web服务于tomcat连接时使用的一种协议,比如通过apache或iis。目前使用此场景较少,当前越来越多的情况下在使用nginx的WEB服务器作为连接中转。此处不再进行详细说明。

Engine节点:

是一个Servlet容器,可以包含该多个虚拟主机(通过Host实现)。主要就是将用户请求分配给每一个虚拟主机进行处理,完成后再将结果返回给Connector。

属性名称
必须
默认值
描述
backgroundProcessorDelayfalse10backgroundProcessor方法指定的间隔时长。取值小于0时将不再执行此方法。法主要用于重新加载 Web 应用程序的类文件、资源和扫描 Session 过期。
classNamefalsetomcat标准实现Engine实现类的全限定名。如果使用自定义实现,此类必须要实现org.apache.catalina.Engine接口。
defaultHosttrue 指定默认的Host,取值必须是已经存在的Host节点的name。
jvmRoutefalse 在负载均衡时使用到的标识符,保证取值必须是集群中唯一性。
nametrue Engine的逻辑名称,在输出日志和错误信息时会使用此名称。
startStopThreadsfalse1

启动和停止Host线程数。

0:使用Runtime.getRuntime().availableProcessors()返回值。

1:使用1个线程。

>1:使用Runtime.getRuntime().availableProcessors()+num个线程。

 

Host节点:

虚拟主机配置

属性名称
必须
默认值
描述
属性名称
必须
默认值
描述
appBasewebapps声明应用程序存放路径,可以是相对路径,也可以是绝对路径。相对路径是$CATALINA_HOME。
xmlBaseconf/<engine_name>/<host_name>指定当前Host节点子节点单独配置路径,可以是相对路径,也可以是绝对路径。相对路径是$CATALINA_HOME。
createDirstrue启动时是否创建appBase和xmlBase路径,如果设置为true,当路径创建失败时,会在日志中进行记录,但不影响启动。
autoDeploytrue是否自动部署。当设置为true,tomcat会监控appBase和xmlBase路径下文件的变化,发生变化后会重新加载所在的应用程序。
backgroundProcessorDelay 同Engine节点。如果没有设置取值,也将会使用Engine中的取值。
classNametomcat标准实现Host实现类的全限定名。使用自定义类时,此类必须要实现org.apache.catalina.Host接口。
deployIgnore 使用表达式的方式指定在deploy时忽略的内容。在autoDeploy和deployOnStartup设置为true时生效。如:“.svn”、“*.bak”。
deployOnStartuptrue如果设置为true,tomcat启动时将会自动加载应用程序。
failCtxIfServletStartFailsfalse如果设置为true,Context中应用程序中load-on-startup>=0的Servlet如果启动发生错误,将会导致所在的Context加载失败。
name 当多个Host存在时,必须要保证唯一性。
startStopThreads1同Engine节点。
undeployOldVersionsfalse
 
posted @ 2017-03-01 17:51 左正 阅读( 29) 评论( 0) 编辑 收藏
 

公告本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/6485463.html/,如需转载请自行联系原作者

 

 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值