如何监控Tomcat服务器

发表于:2009-06-25来源:作者:点击数:2651 标签:tomcatTomcat服务器
在进行 性能测试 时,一般都需要对应用服务器进行监控,监控的指标包括应用服务器的JVM使用状况、可用连接数、队列长度等信息。商业的应用服务器如 WebLogic 、 WebSphere 等都提供了Console对这些指标进行监控,在性能测试时可以很容易观察这些指标的情况。

在进行性能测试时,一般都需要对应用服务器进行监控,监控的指标包括应用服务器的JVM使用状况、可用连接数、队列长度等信息。商业的应用服务器如WebLogicWebSphere等都提供了Console对这些指标进行监控,在性能测试时可以很容易观察这些指标的情况。

  Tomcat作为在国内得到广泛应用的J2EE服务器,在不少项目中都得到了使用。Tomcat小巧灵活、配置简单,非常适合小的WEB应用使用。但在对使用Tomcat的应用系统进行性能测试时,最头疼的问题就是不能获得应用服务器的相关性能指标数据。

 
 其实,从Tomcat 5.0开始,Tomcat就已经为自己提供了一个用于监控应用服务器性能指标的servelet —— status
servelet。安装完Tomcat 5之后,通过访问 http://yourhost:port/manager/status
就可以获得当时的应用服务器监控数据。

  当然,为了安全起见,Tomcat 5在缺省安装时是不允许用户直接访问 http://yourhost:port/manager/status 的,访问的时候会给出一个403(forbidden)的错误信息。在Tomcat的Manual里说明了允许用户访问的方法:

1. 转到Tomcat的安装目录下;
   2. 修改conf/tomcat-users.xml文件,在其中加入一行  <user username="servermon" password="passwd" roles="manager"/>

  这样就可以在访问 http://yourhost:port/manager/status 时给出 servermon 的用户名与口令,查看到应用服务器的相关性能指标数据。

You are not authorized to view this page. If you have not changed any configuration files, please examine the file conf/tomcat-users.xml in your installation. That file must contain the credentials to let you use this webapp.

For example, to add the manager-gui role to a user named tomcat with a password of s3cret, add the following to the config file listed above.

<role rolename="manager-gui"/>
<user username="tomcat" password="s3cret" roles="manager-gui"/>

Note that for Tomcat 7 onwards, the roles required to use the manager application were changed from the single manager role to the following four roles. You will need to assign the role(s) required for the functionality you wish to access.

  • manager-gui - allows access to the HTML GUI and the status pages
  • manager-script - allows access to the text interface and the status pages
  • manager-jmx - allows access to the JMX proxy and the status pages
  • manager-status - allows access to the status pages only

The HTML interface is protected against CSRF but the text and JMX interfaces are not. To maintain the CSRF protection:

  • Users with the manager-gui role should not be granted either the manager-script or manager-jmx roles.
  • If the text or jmx interfaces are accessed through a browser (e.g. for testing since these interfaces are intended for tools not humans) then the browser must be closed afterwards to terminate the session.

For more information - please see the Manager App HOW-TO.

*************************************************************************************************************************************************************************************

前言:做了一个监控应用服务器的项目(支持Tocmat、WebSphere、WebLogic各版本), 过程也算是磕磕绊绊,由于网上缺少相关资料,或者深陷于知识的海洋难以寻觅到有效的资料,因而走过不少弯路,遇过不少困难。为了留下点印记,给后来人留下 点经验之谈,助之少走弯路,故将这些经验整理出来,与大家分享。水平有限,难免疏漏,还望指正。如有疑问,欢迎留言,或者加入Q群参与讨 论:35526521。

监控Tomcat的常见方案有两种,比较如下:

方案一、使用Tomcat提供的manager应用进行数据采集
◆ 可以使用现有的成熟代码,减少工作量
◆ 支持各不同版本时无差别
◆ 可能存在特殊需求而manager不能满足的情况

◆ 最重要的一个优点是,配置比较简单

方案二、使用JMX接口开发监控程序
◆ 全部代码需要从零开始,代码量较大
◆ 支持各不同版本比较麻烦,每个版本可能有差异
◆ 可支配性强

◆ 最重要的一个缺点是,配置比较麻烦

方案一、使用 Tomcat提供的manager应用进行数据采集
Applications Manager(又称opManager)就是通过这种方式实现的。
使用这种方式,所监控Tomcat必须运行manager应用,缺省情况下,该应用总是运行在服务器中的。

增加manager角色用户

访问manager应用的用户的角色权限必须是 manager.
修改<TOMCAT_HOME>/conf目录下的tomcat-users.xml文件,在<tomcat-users>节点下添加一个user节点,即可创建一个用户。

Tomcat版本不同配置也有差异,5.x和6.x创建的用户角色应为manager,7.x创建的用户角色为manager-jmx,举例如下:

1、在5.x和6.x中创建一个manager角色的用户,用户名为admin,密码为chenfeng:
    <user username="admin" password="chenfeng" roles="manager"/>

2、在7.x中创建一个manager角色的用户,用户名为admin,密码为chenfeng:
    <user username="admin" password="chenfeng" roles="manager-jmx,manager-script,manager-status"/>

修改配置后,需要重新启动 Tomcat 服务器。
连接manager时将用户名/密码指定为admin/chenfeng

通过浏览器访问JMX Proxy Servlet

详见官方说明文档:
http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html#Using_the_JMX_Proxy_Servlet

What is JMX Proxy Servlet

  1. The JMX Proxy Servlet is a lightweight proxy to get and set the tomcat internals. (Or any class that has been exposed via an MBean) Its usage is not very user friendly but the UI is extremely help for integrating command line scripts for monitoring and changing the internals of tomcat. You can do two things with the proxy: get information and set information. For you to really understand the JMX Proxy Servlet, you should have a general understanding of JMX. If you don't know what JMX is, then prepare to be confused.

JMX Query command

  1. This takes the form:
  2. http://webserver/manager/jmxproxy/?qry=STUFF
  3. Where STUFF is the JMX query you wish to perform. For example, here are some queries you might wish to run:
  4. ◆ qry=*%3Atype%3DRequestProcessor%2C* --> type=RequestProcessorwhich will locate all workers which can process requests and report their state.
  5. ◆ qry=*%3Aj2eeType=Servlet%2c* --> j2eeType=Servletwhich return all loaded servlets.
  6. ◆ qry=Catalina%3Atype%3DEnvironment%2Cresourcetype%3DGlobal%2Cname%3DsimpleValue --> Catalina:type=Environment,resourcetype=Global,name=simpleValuewhich look for a specific MBean by the given name.
  7. You'll need to experiment with this to really understand its capabilites. If you provide no qry parameter, then all of the MBeans will be displayed. We really recommend looking at the tomcat source code and understand the JMX spec to get a better understanding of all the queries you may run.

通过浏览器访问http://localhost:8080/manager/jmxproxy ,输入用户名密码,然后就可以看到返回了所有的监控信息

添加查询参数,返回特定的监控信息:
例如:

http://localhost:8080/manager/jmxproxy?qry=*%3Atype%3DRequestProcessor%2C*

其中 *%3Atype%3DRequestProcessor%2C* 其实就是 *:type=RequestProcessor,*

又如:

http://localhost:8080/manager/jmxproxy?qry=*%3Aj2eeType%3DWebModule%2Cname%3D//localhost/ajaxrpc%2C*

在代码中访问JMX Proxy Servlet

通过浏览器访问JMX Proxy Servlet需要输入用户名密码,所以通过Java访问JMX Proxy Servlet的URL也需要授权访问: URL url = new URL("http://localhost:8080/manager/jmxproxy?qry=*%3Atype%3DManager%2C*");

  1. URLConnection conn = (URLConnection) url.openConnection();
  2. // URL授权访问 -- Begin
  3. String password = "admin:chenfeng"; // manager角色的用户
  4. String encodedPassword = new BASE64Encoder().encode(password.getBytes());
  5. conn.setRequestProperty("Authorization", "Basic " + encodedPassword);
  6. // URL授权访问 -- End
  7. InputStream is = conn.getInputStream();
  8. BufferedReader bufreader = new BufferedReader(new InputStreamReader(is));
  9. String line = null;
  10. while ((line = bufreader.readLine()) != null) {
  11. System.out.println(line);
  12. }

几个具体的例子

下面展示两个例子,一个是采集服务器基本信息,一个是采集Web应用列表信息,注意Tomcat 7.x和Tomcat 5.x、6.x之间存在很大的区别。

◆ 采集服务器基本信息

通过serverinfo命令查看服务器基本信息
     http://localhost:8080/manager/serverinfo

Tomcat 7.x的查询URL有变化:
     http://localhost:8080/manager/text/serverinfo

返回信息:

  1. OK - Server info
  2. Tomcat Version: Apache Tomcat/7.0.11
  3. OS Name: Windows Vista
  4. OS Version: 6.1
  5. OS Architecture: x86
  6. JVM Version: 1.6.0_13-b03
  7. JVM Vendor: Sun Microsystems Inc.

◆ 采集Web应用列表信息

通过list命令查看Web应用列表和会话数信息
     http://localhost:8080/manager/list

Tomcat 7.x的查询URL有变化:
     http://localhost:8080/manager/text/list

返回信息:

  1. OK - Listed applications for virtual host localhost
  2. /:running:0:ROOT
  3. /manager:running:1:manager
  4. /docs:running:0:docs
  5. /examples:running:0:examples
  6. /host-manager:running:0:host-manager

方案二、使用JMX 接口开发监控程序

Tomcat激活JMX远程配置

① 先修改Tomcat的启动脚本,window下tomcat的bin/catalina.bat(linux为catalina.sh),添加以下内 容,8999是jmxremote使用的端口号,第二个false表示不需要鉴权:

  1. set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
  2. set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG%

可以加在if "%OS%" == "Windows_NT" setlocal 一句后的大段的注释后面。

参考官方说明:
http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote

② 上面的配置是不需要鉴权的,如果需要鉴权则添加的内容为:

  1. set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
  2. set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG%

然后复制并修改授权文件,$JAVA_HOME/jre/lib/management下有 jmxremote.access和jmxremote.password的模板文件,将两个文件复制到$CATALINA_BASE/conf目录下
● 修改$CATALINA_BASE/conf/jmxremote.access 添加内容:
     monitorRole readonly
     controlRole readwrite

● 修改$CATALINA_BASE/conf/jmxremote.password 添加内容:
     monitorRole tomcat
     controlRole tomcat

注意:如果只做第一步没有问题,进行了第二步Tomcat就启动不了,那么很可能是密码文件的权限问题!
需要修改jmxremote.password文件的权限,只有运行Tomcat的用户有访问权限:
Windows的NTFS文件系统下,选中文件,点右键 -->“属性”-->“安全”--> 点“高级”-->
点“更改权限”--> 去掉“从父项继承....”--> 弹出窗口中选“删除”,这样就删除了所有访问权限。再选“添加”-->
“高级”-->
“立即查找”,选中你的用户,例administrator,点“确定",“确定"。来到权限项目窗口,勾选“完全控制”,点“确定”,OK了。

官方的提示
The password file should be read-only and only accessible by the operating system user Tomcat is running as.

③ 重新启动Tomcat,在Windows命令行输入“netstat -a”查看配置的端口号是否已打开,如果打开,说明上面的配置成功了。

④ 使用jconsole测试JMX。

运行$JAVA_HOME/bin目录下的jconsole.exe,打开
J2SE监视和管理控制台,然后建立连接,如
果是本地的Tomcat则直接选择然后点击连接,如果是远程的,则进入远程选项卡,填写地址、端口号、用户名、口令即可连接。Mbean属性页中给出了相
应的数据,Catalina中是tomcat的,java.lang是jvm的。对于加粗的黑体属性值,需双击一下才可看内容。

使用JMX监控Tomcat示例代码:

  1. String jmxURL = "service:jmx:rmi:///jndi/rmi://192.168.10.93:8999/jmxrmi";
  2. JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);
  3. Map map = new HashMap();
  4. // 用户名密码,在jmxremote.password文件中查看
  5. String[] credentials = new String[] { "monitorRole", "tomcat" };
  6. map.put("jmx.remote.credentials", credentials);
  7. JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map);
  8. MBeanServerConnection mbsc = connector.getMBeanServerConnection();
  9. // 端口最好是动态取得
  10. ObjectName threadObjName = new ObjectName("Catalina:type=ThreadPool,name=http-8080");
  11. MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName);
  12. // tomcat的线程数对应的属性值
  13. String attrName = "currentThreadCount";
  14. MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes();
  15. System.out.println("currentThreadCount:" + mbsc.getAttribute(threadObjName, attrName));

完整的示例代码文件:

    1. import java.lang.management.MemoryUsage;
    2. import java.text.SimpleDateFormat;
    3. import java.util.Date;
    4. import java.util.Formatter;
    5. import java.util.HashMap;
    6. import java.util.Iterator;
    7. import java.util.Map;
    8. import java.util.Set;
    9. import javax.management.MBeanAttributeInfo;
    10. import javax.management.MBeanInfo;
    11. import javax.management.MBeanServerConnection;
    12. import javax.management.ObjectInstance;
    13. import javax.management.ObjectName;
    14. import javax.management.openmbean.CompositeDataSupport;
    15. import javax.management.remote.JMXConnector;
    16. import javax.management.remote.JMXConnectorFactory;
    17. import javax.management.remote.JMXServiceURL;
    18. /**
    19. * 使用JMX监控Tomcat示例
    20. *
    21. * @author 陳峰
    22. */
    23. public class JMXTest {
    24. /**
    25. * @param args
    26. */
    27. public static void main(String[] args) {
    28. try {
    29. String jmxURL = "service:jmx:rmi:///jndi/rmi://127.0.0.1:8999/jmxrmi";
    30. JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);
    31. Map map = new HashMap();
    32. String[] credentials = new String[] { "monitorRole", "tomcat" };
    33. map.put("jmx.remote.credentials", credentials);
    34. JMXConnector connector = JMXConnectorFactory.connect(serviceURL,
    35. map);
    36. MBeanServerConnection mbsc = connector.getMBeanServerConnection();
    37. // 端口最好是动态取得
    38. ObjectName threadObjName = new ObjectName(
    39. "Catalina:type=ThreadPool,name=http-8080");
    40. MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName);
    41. String attrName = "currentThreadCount";// tomcat的线程数对应的属性值
    42. MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes();
    43. System.out.println("currentThreadCount:"
    44. + mbsc.getAttribute(threadObjName, attrName));
    45. // heap
    46. for (int j = 0; j < mbsc.getDomains().length; j++) {
    47. System.out.println("###########" + mbsc.getDomains()[j]);
    48. }
    49. Set MBeanset = mbsc.queryMBeans(null, null);
    50. System.out.println("MBeanset.size() : " + MBeanset.size());
    51. Iterator MBeansetIterator = MBeanset.iterator();
    52. while (MBeansetIterator.hasNext()) {
    53. ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator
    54. .next();
    55. ObjectName objectName = objectInstance.getObjectName();
    56. String canonicalName = objectName.getCanonicalName();
    57. System.out.println("canonicalName : " + canonicalName);
    58. if (canonicalName
    59. .equals("Catalina:host=localhost,type=Cluster")) {
    60. // Get details of cluster MBeans
    61. System.out.println("Cluster MBeans Details:");
    62. System.out
    63. .println("=========================================");
    64. // getMBeansDetails(canonicalName);
    65. String canonicalKeyPropList = objectName
    66. .getCanonicalKeyPropertyListString();
    67. }
    68. }
    69. // ------------------------- system ----------------------
    70. ObjectName runtimeObjName = new ObjectName("java.lang:type=Runtime");
    71. System.out.println("厂商:"
    72. + (String) mbsc.getAttribute(runtimeObjName, "VmVendor"));
    73. System.out.println("程序:"
    74. + (String) mbsc.getAttribute(runtimeObjName, "VmName"));
    75. System.out.println("版本:"
    76. + (String) mbsc.getAttribute(runtimeObjName, "VmVersion"));
    77. Date starttime = new Date((Long) mbsc.getAttribute(runtimeObjName,
    78. "StartTime"));
    79. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    80. System.out.println("启动时间:" + df.format(starttime));
    81. Long timespan = (Long) mbsc.getAttribute(runtimeObjName, "Uptime");
    82. System.out.println("连续工作时间:" + JMXTest.formatTimeSpan(timespan));
    83. // ------------------------ JVM -------------------------
    84. // 堆使用率
    85. ObjectName heapObjName = new ObjectName("java.lang:type=Memory");
    86. MemoryUsage heapMemoryUsage = MemoryUsage
    87. .from((CompositeDataSupport) mbsc.getAttribute(heapObjName,
    88. "HeapMemoryUsage"));
    89. long maxMemory = heapMemoryUsage.getMax();// 堆最大
    90. long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配
    91. long usedMemory = heapMemoryUsage.getUsed();
    92. System.out.println("heap:" + (double) usedMemory * 100
    93. / commitMemory + "%");// 堆使用率
    94. MemoryUsage nonheapMemoryUsage = MemoryUsage
    95. .from((CompositeDataSupport) mbsc.getAttribute(heapObjName,
    96. "NonHeapMemoryUsage"));
    97. long noncommitMemory = nonheapMemoryUsage.getCommitted();
    98. long nonusedMemory = heapMemoryUsage.getUsed();
    99. System.out.println("nonheap:" + (double) nonusedMemory * 100
    100. / noncommitMemory + "%");
    101. ObjectName permObjName = new ObjectName(
    102. "java.lang:type=MemoryPool,name=Perm Gen");
    103. MemoryUsage permGenUsage = MemoryUsage
    104. .from((CompositeDataSupport) mbsc.getAttribute(permObjName,
    105. "Usage"));
    106. long committed = permGenUsage.getCommitted();// 持久堆大小
    107. long used = heapMemoryUsage.getUsed();//
    108. System.out.println("perm gen:" + (double) used * 100 / committed
    109. + "%");// 持久堆使用率
    110. // -------------------- Session ---------------
    111. ObjectName managerObjName = new ObjectName(
    112. "Catalina:type=Manager,*");
    113. Set<ObjectName> s = mbsc.queryNames(managerObjName, null);
    114. for (ObjectName obj : s) {
    115. System.out.println("应用名:" + obj.getKeyProperty("path"));
    116. ObjectName objname = new ObjectName(obj.getCanonicalName());
    117. System.out.println("最大会话数:"
    118. + mbsc.getAttribute(objname, "maxActiveSessions"));
    119. System.out.println("会话数:"
    120. + mbsc.getAttribute(objname, "activeSessions"));
    121. System.out.println("活动会话数:"
    122. + mbsc.getAttribute(objname, "sessionCounter"));
    123. }
    124. // ----------------- Thread Pool ----------------
    125. ObjectName threadpoolObjName = new ObjectName(
    126. "Catalina:type=ThreadPool,*");
    127. Set<ObjectName> s2 = mbsc.queryNames(threadpoolObjName, null);
    128. for (ObjectName obj : s2) {
    129. System.out.println("端口名:" + obj.getKeyProperty("name"));
    130. ObjectName objname = new ObjectName(obj.getCanonicalName());
    131. System.out.println("最大线程数:"
    132. + mbsc.getAttribute(objname, "maxThreads"));
    133. System.out.println("当前线程数:"
    134. + mbsc.getAttribute(objname, "currentThreadCount"));
    135. System.out.println("繁忙线程数:"
    136. + mbsc.getAttribute(objname, "currentThreadsBusy"));
    137. }
    138. } catch (Exception e) {
    139. e.printStackTrace();
    140. }
    141. }
    142. public static String formatTimeSpan(long span) {
    143. long minseconds = span % 1000;
    144. span = span / 1000;
    145. long seconds = span % 60;
    146. span = span / 60;
    147. long mins = span % 60;
    148. span = span / 60;
    149. long hours = span % 24;
    150. span = span / 24;
    151. long days = span;
    152. return (new Formatter()).format("%1$d天 %2$02d:%3$02d:%4$02d.%5$03d",
    153. days, hours, mins, seconds, minseconds).toString();
    154. }
    155. }

如何监控Tomcat服务器的更多相关文章

  1. LR监控tomcat服务器

    采用编写VuGen脚本访问Tomcat的Status页面的方式获取性能数据(利用了关联和lr_user_data_point函数),本质上还是使用tomcat自带的监控页面,只是将监控结果加到LR的a ...

  2. 服务器上监控tomcat,如果挂掉则重启

    该脚本用于监控tomcat服务器是否可用,如果服务不可用则重启tomcat 略微修改后也可以用于其他服务的监控 monitor.sh 脚本如下 #!/bin/sh # 定义要监控的页面地址 WebUr ...

  3. 运用JMX监控Tomcat/Java jvisualvm简要说明

    公司线上项目出现了java heap space 然后经过查询知晓了下面工具于是开始了尝试. visualvm能干什么:监控内存泄露,跟踪垃圾回收,执行时内存.cpu分析,线程分析... jvisua ...

  4. JaCoCo在Tomcat服务器上监控代码覆盖率的使用方法

    简介 Jacoco是一个开源的覆盖率工具.Jacoco可以嵌入到Ant .Maven中,并提供了EclEmma Eclipse插件,也可以使用JavaAgent技术监控Java程序.很多第三方的工具提 ...

  5. Windows负载机JVM 远程监控Linux服务器下tomcat

    基本是跟着网上的操作进行的,除了遇到一个Local host name unknown的问题: 一.Linux服务器操作部分 服务器地址:10.64.111.68 首先配置JMX: 1.找到jdk目录 ...

  6. cacti系列(二)之cacti添加对tomcat服务器的监控

    cacti添加对tomcat的监控 1.首先下载监控tomcat的模板 TomcatStats-0.1.zip    2.导入模板 (cacti_host_template_tomcat_server ...

  7. Tomcat服务器原理详解

    [目录]本文主要讲解Tomcat启动和部署webapp时的原理和过程,以及其使用的配置文件的详解.主要有三大部分: 第一部分.Tomcat的简介和启动过程 第二部分.Tomcat部署webapp 第三 ...

  8. JMeter监控Linux服务器资源案例

    JMeter是一款压力测试工具,我们也可以用它来监控服务器资源使用情况.JMeter正常自带可以通过Tomcat的/manager/status来监控服务资源使用情况.这种情况只能监控Tomcat支持 ...

  9. LoadRunner如何监控Tomcat性能

    使用LoadRunner做性能测试,一般的直觉是LR只能完成脚本录制和编写模拟用户的请求行为,但是在某些情况下,要监控一些中间件或web服务器的性能时,就不能通过录制脚本来完成了,那么就需要手工来编写 ...

随机推荐

  1. Python开发基础-Day4-布尔运算、集合

    布尔值 True 真 False 假 所有的数据类型都自带布尔值,数据只有在0,None和空的时候为False. print(bool()) print(bool()) print(bool('')) ...

  2. luogu P1012 拼数

    题目描述 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213 又如:n=4时,4个整数7,13,4 ...

  3. 【POJ】1088滑雪

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 97335   Accepted: 36911 Description ...

  4. 【启发式搜索】【A*算法】hdu6171 Admiral

    一个舰队的目标状态如上图.红色是旗舰.然后给你初始局面,每一次决策可以把旗舰和其上一层或下一层的两个相邻的进行交换.如果能在20步内出解的话,输出最小步数:否则输出“too difficult”. 把 ...

  5. 【点分治】【FFT】Gym - 101234D - Forest Game

    存个求树上每种长度(长度定义为路径上点数)的路径条数的模板:num数组中除了长度为1的以外,都算了2次. 不造为啥FFT数组要开八倍. #include<cstdio> #include& ...

  6. 5月学习总结(Ant-Design,mustache,require.js,grunt)

    一.Ant-Design学习 因为Ant-Design是基于React实现的,之前自己也学过一段时间的React,对React还是相对比较熟悉的,在学习Ant-Design也还不算吃力. 最开始是从源 ...

  7. mongodb安装和配置,遇到问题和解决方法

    自己不知道怎么的,心血来潮想重新来安装和配置一下mongodb,之前自己也是按照别人的来整的,印象不深刻.第二遍安装配置遇到很多问题. 弄了两个多小时,期间遇到很多问题: 遇到的主要问题 1.拒绝访问 ...

  8. [译]SQL数据库迁移:从低版到高版本

    我见过太多的数据库管理员花大量的时间在数据库迁移上,即便在客户的实际环境亦是如此.由于微软频繁的发布新版,基于业务和客户的要求,应用服务不得不同时升级.当然,还有许多用户仍在使用SQL Server ...

  9. uboot如何检测XC2440是从Nand或Nor启动

    转:http://blog.chinaunix.net/uid-22030783-id-3347621.html 在XC2440开发板上做uboot从nandflash启动时,需要检测硬件启动方式,启 ...

  10. 生成SESSIONID

    生成SESSIONID uses SynCommons procedure TForm1.Button1Click(Sender: TObject);var i: Cardinal;begin i : ...