故障排除

检查WFS请求

用户经常报告手工创建的WFS请求不能按预期工作的问题。在大多数情况下,请求是错误的,但Geoserver不会抱怨,只是忽略错误的部分(这种行为是使较旧的WFS客户端与Geoserver一起正常工作的默认行为)。

如果希望geoserver验证大多数WFS XML请求,可以将其发布到以下URL::

http://host:port/geoserver/ows?strict=true

与所需结构的任何偏差将在错误消息中注明。在任何情况下,唯一未验证的请求类型是插入类型(这是一个geoserver自己的限制)。

利用geoserver自己的日志

地理服务器可以在 $GEOSERVER_DATA_DIR/logs/geoserver.log 文件。查找此类文件是解决问题时首先要做的事情之一,特别是查看与错误请求对应的日志内容非常有趣。根据在中选择的日志配置文件,记录的信息量可能有所不同。 服务器设置 配置页。

日志记录服务请求

Geoserver提供默认情况下处于非活动状态的请求记录功能。在中启用时 global settings Geoserver可以记录请求的URL和POST请求内容。

../_images/request_logging_settings.png

全局设置

要跟踪传入请求的历史记录,请执行以下操作:

  1. 通过导航到以下位置启用请求记录 Settings > Global 页面,向下滚动到 Logging Settings ,以及 Enable Request Logging

  2. 使用以下选项启用此功能 Enable Request Logging

  3. 可选的选择 Log Request Bodies 对POST或PUT请求(例如,WFS事务)进行故障排除。要记录的字符数设置将对记录的数据量设置上限,以避免与记录相关的性能问题。

  4. 可选的选择 Log Request Headers 排除请求标头的故障(例如,在检查安全凭据时)。

  5. 单击 Apply 以应用这些设置。

  6. 这将记录请求信息,结果如下:

    08 gen 11:30:13 INFO [geoserver.filters] - 127.0.0.1 "GET /geoserver/wms?HEIGHT=330&WIDTH=660&LAYERS=nurc%3AArc_Sample&STYLES=&SRS=EPSG%3A4326&FORMAT=image%2Fjpeg&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&BBOX=-93.515625,-40.078125,138.515625,75.9375" "Mozilla/5.0 (X11; U; Linux i686; it; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15" "http://localhost:8080/geoserver/wms?service=WMS&version=1.1.0&request=GetMap&layers=nurc:Arc_Sample&styles=&bbox=-180.0,-90.0,180.0,90.0&width=660&height=330&srs=EPSG:4326&format=application/openlayers"
    08 gen 11:30:13 INFO [geoserver.filters] - 127.0.0.1 "GET /geoserver/wms?HEIGHT=330&WIDTH=660&LAYERS=nurc%3AArc_Sample&STYLES=&SRS=EPSG%3A4326&FORMAT=image%2Fjpeg&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&BBOX=-93.515625,-40.078125,138.515625,75.9375" took 467ms
    08 gen 11:30:14 INFO [geoserver.filters] - 127.0.0.1 "GET /geoserver/wms?REQUEST=GetFeatureInfo&EXCEPTIONS=application%2Fvnd.ogc.se_xml&BBOX=-93.515625%2C-40.078125%2C138.515625%2C75.9375&X=481&Y=222&INFO_FORMAT=text%2Fhtml&QUERY_LAYERS=nurc%3AArc_Sample&FEATURE_COUNT=50&Layers=nurc%3AArc_Sample&Styles=&Srs=EPSG%3A4326&WIDTH=660&HEIGHT=330&format=image%2Fjpeg" "Mozilla/5.0 (X11; U; Linux i686; it; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15" "http://localhost:8080/geoserver/wms?service=WMS&version=1.1.0&request=GetMap&layers=nurc:Arc_Sample&styles=&bbox=-180.0,-90.0,180.0,90.0&width=660&height=330&srs=EPSG:4326&format=application/openlayers"
    08 gen 11:30:14 INFO [geoserver.filters] - 127.0.0.1 "GET /geoserver/wms?REQUEST=GetFeatureInfo&EXCEPTIONS=application%2Fvnd.ogc.se_xml&BBOX=-93.515625%2C-40.078125%2C138.515625%2C75.9375&X=481&Y=222&INFO_FORMAT=text%2Fhtml&QUERY_LAYERS=nurc%3AArc_Sample&FEATURE_COUNT=50&Layers=nurc%3AArc_Sample&Styles=&Srs=EPSG%3A4326&WIDTH=660&HEIGHT=330&format=image%2Fjpeg" took 314ms
    

服务器状态JVM控制台

Geoserver提供了内置的 JVM控制台 用于获得:

  • 线程转储信息

  • 堆转储信息

此页面可用于检查当前状态并下载结果以供仔细查看。

../_images/thread_dump.png

JVM控制台

使用JDK工具获取堆栈和内存转储

JDK包含三个有用的命令行工具,可用于收集有关正在泄漏内存或未按要求执行的地理服务器实例的信息: jpsjstackjmap .

所有的工具都是针对一个活的Java虚拟机,特别是运行GeoServer的。为了让它们正常工作,您必须使用具有足够权限连接到JVM进程的用户来运行它们,特别是超级用户或运行JVM的同一用户通常具有所需的权限。

日元

jps 是一个列出所有正在运行的Java进程的工具。它可用于检索 pid 运行Geoserver的虚拟机的(进程ID)。例如::

> jps -mlv

16235 org.apache.catalina.startup.Bootstrap start -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=/home/aaime/devel/webcontainers/apache-tomcat-6.0.18/conf/logging.properties -Djava.endorsed.dirs=/home/aaime/devel/webcontainers/apache-tomcat-6.0.18/endorsed -Dcatalina.base=/home/aaime/devel/webcontainers/apache-tomcat-6.0.18 -Dcatalina.home=/home/aaime/devel/webcontainers/apache-tomcat-6.0.18 -Djava.io.tmpdir=/home/aaime/devel/webcontainers/apache-tomcat-6.0.18/temp
11521  -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -Djava.library.path=/usr/lib/jni -Dosgi.requiredJavaVersion=1.5 -XX:MaxPermSize=256m -Xms64m -Xmx1024m -XX:CMSClassUnloadingEnabled -XX:CMSPermGenSweepingEnabled -XX:+UseParNewGC
16287 sun.tools.jps.Jps -mlv -Dapplication.home=/usr/lib/jvm/java-6-sun-1.6.0.16 -Xms8m

输出显示 pid ,主类名(如果可用),以及在启动时传递给JVM的参数。在这个例子中 16235 是Tomcat托管geoserver, 11521 是Eclipse实例,并且 16287jps 本身。在一般情况下,您只有很少的JVM,并且运行geoserver的JVM可以通过传递给它的参数来标识。

J定位

jstack 是一个用于提取在虚拟机中运行的每个线程的当前堆栈跟踪的工具。它可以用来识别可伸缩性问题,并收集程序实际在做什么。

它通常需要详细了解Geoserver的内部工作原理,才能正确解释jStack输出。

用法示例:

> jstack -F -l 16235 > /tmp/tomcat-stack.txt
Attaching to process ID 16235, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 14.2-b01

文件内容可能如下:

Deadlock Detection:

No deadlocks found.

Thread 16269: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable.run() @bci=10, line=565 (Interpreted frame)
 - java.lang.Thread.run() @bci=11, line=619 (Interpreted frame)

Locked ownable synchronizers:
    - None

Thread 16268: (state = IN_NATIVE)
 - java.net.PlainSocketImpl.socketAccept(java.net.SocketImpl) @bci=0 (Interpreted frame)
 - java.net.PlainSocketImpl.accept(java.net.SocketImpl) @bci=7, line=390 (Interpreted frame)
 - java.net.ServerSocket.implAccept(java.net.Socket) @bci=60, line=453 (Interpreted frame)
 - java.net.ServerSocket.accept() @bci=48, line=421 (Interpreted frame)
 - org.apache.jk.common.ChannelSocket.accept(org.apache.jk.core.MsgContext) @bci=46, line=306 (Interpreted frame)
 - org.apache.jk.common.ChannelSocket.acceptConnections() @bci=72, line=660 (Interpreted frame)
 - org.apache.jk.common.ChannelSocket$SocketAcceptor.runIt(java.lang.Object[]) @bci=4, line=870 (Interpreted frame)
 - org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run() @bci=167, line=690 (Interpreted frame)
 - java.lang.Thread.run() @bci=11, line=619 (Interpreted frame)

Locked ownable synchronizers:
    - None

Thread 16267: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.Object.wait() @bci=2, line=485 (Interpreted frame)
 - org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run() @bci=26, line=662 (Interpreted frame)
 - java.lang.Thread.run() @bci=11, line=619 (Interpreted frame)

Locked ownable synchronizers:
    - None

...

内存图

jmap 是一个用于收集有关Java虚拟机的信息的工具。它可以以几种有趣的方式使用。

通过不带参数(而不是JVM的进程ID)运行它,它将输出一个 dump of the native libraries used by the JVM 。当用户想要再次检查Geoserver是否实际使用了某个版本的本地库(例如,GDAL)时,这会很方便:

> jmap 17251

Attaching to process ID 17251, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 14.2-b01
0x08048000  46K   /usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java
0x7f87f000  6406K /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libNCSEcw.so.0
0x7f9b2000  928K  /usr/lib/libstdc++.so.6.0.10
0x7faa1000  7275K /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libgdal.so.1
0x800e9000  1208K /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libclib_jiio.so
0x80320000  712K  /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libNCSUtil.so.0
0x80343000  500K  /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libNCSCnet.so.0
0x8035a000  53K   /lib/libgcc_s.so.1
0x8036c000  36K   /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libnio.so
0x803e2000  608K  /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libawt.so
0x80801000  101K  /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libgdaljni.so
0x80830000  26K   /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/headless/libmawt.so
0x81229000  93K   /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libnet.so
0xb7179000  74K   /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libzip.so
0xb718a000  41K   /lib/tls/i686/cmov/libnss_files-2.9.so
0xb7196000  37K   /lib/tls/i686/cmov/libnss_nis-2.9.so
0xb71b3000  85K   /lib/tls/i686/cmov/libnsl-2.9.so
0xb71ce000  29K   /lib/tls/i686/cmov/libnss_compat-2.9.so
0xb71d7000  37K   /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/native_threads/libhpi.so
0xb71de000  184K  /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libjava.so
0xb7203000  29K   /lib/tls/i686/cmov/librt-2.9.so
0xb725d000  145K  /lib/tls/i686/cmov/libm-2.9.so
0xb7283000  8965K /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/server/libjvm.so
0xb7dc1000  1408K /lib/tls/i686/cmov/libc-2.9.so
0xb7f24000  9K    /lib/tls/i686/cmov/libdl-2.9.so
0xb7f28000  37K   /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/jli/libjli.so
0xb7f32000  113K  /lib/tls/i686/cmov/libpthread-2.9.so
0xb7f51000  55K   /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libverify.so
0xb7f60000  114K  /lib/ld-2.9.so

也有可能得到 JVM堆状态的快速摘要 ::

> jmap -heap 17251

Attaching to process ID 17251, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 14.2-b01

using thread-local object allocation.
Parallel GC with 2 thread(s)

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 778043392 (742.0MB)
   NewSize          = 1048576 (1.0MB)
   MaxNewSize       = 4294901760 (4095.9375MB)
   OldSize          = 4194304 (4.0MB)
   NewRatio         = 8
   SurvivorRatio    = 8
   PermSize         = 16777216 (16.0MB)
   MaxPermSize      = 67108864 (64.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 42401792 (40.4375MB)
   used     = 14401328 (13.734176635742188MB)
   free     = 28000464 (26.703323364257812MB)
   33.96396076845054% used
From Space:
   capacity = 4718592 (4.5MB)
   used     = 2340640 (2.232208251953125MB)
   free     = 2377952 (2.267791748046875MB)
   49.60462782118056% used
To Space:
   capacity = 4587520 (4.375MB)
   used     = 0 (0.0MB)
   free     = 4587520 (4.375MB)
   0.0% used
PS Old Generation
   capacity = 43188224 (41.1875MB)
   used     = 27294848 (26.0303955078125MB)
   free     = 15893376 (15.1571044921875MB)
   63.19974630121396% used
PS Perm Generation
   capacity = 38404096 (36.625MB)
   used     = 38378640 (36.60072326660156MB)
   free     = 25456 (0.0242767333984375MB)
   99.93371540369027% used

结果可以看出,允许JVM使用多达742MB的内存,而目前JVM使用130MB(每个堆段的容量的粗略总和)。如果发生持久性内存泄漏,JVM将最终使用允许使用的任何内容,堆的每个部分将几乎100%地被使用。

去看看 记忆是如何被简洁地使用的 可以使用以下命令(在Windows上,替换 head -25 具有 more ):

> jmap -histo:live 17251 | head -25

 num     #instances         #bytes  class name
----------------------------------------------
   1:         81668       10083280  <constMethodKlass>
   2:         81668        6539632  <methodKlass>
   3:         79795        5904728  [C
   4:        123511        5272448  <symbolKlass>
   5:          7974        4538688  <constantPoolKlass>
   6:         98726        3949040  org.hsqldb.DiskNode
   7:          7974        3612808  <instanceKlassKlass>
   8:          9676        2517160  [B
   9:          6235        2465488  <constantPoolCacheKlass>
  10:         10054        2303368  [I
  11:         83121        1994904  java.lang.String
  12:         27794        1754360  [Ljava.lang.Object;
  13:          9227         868000  [Ljava.util.HashMap$Entry;
  14:          8492         815232  java.lang.Class
  15:         10645         710208  [S
  16:         14420         576800  org.hsqldb.CachedRow
  17:          1927         574480  <methodDataKlass>
  18:          8937         571968  org.apache.xerces.dom.ElementNSImpl
  19:         12898         561776  [[I
  20:         23122         554928  java.util.HashMap$Entry
  21:         16910         541120  org.apache.xerces.dom.TextImpl
  22:          9898         395920  org.apache.xerces.dom.AttrNSImpl

通过转储,我们可以看到大部分内存由geoserver代码本身(前5项)使用,接着是包含几行epsg数据库的hsql缓存。在内存泄漏的情况下,一些对象类型将占据绝大多数活动堆。注意,要查找泄漏,应该在服务器几乎空闲的情况下收集转储文件。例如,如果服务器正在加载getmap请求,则主内存使用量将是呈现图像时保存图像的字节[],但这不是泄漏,这是合法的临时使用。

如果内存泄漏,开发人员可能会要求 完全堆转储 使用高端分析工具进行分析。可以使用以下命令生成此类转储:

> jmap -dump:live,file=/tmp/dump.hprof 17251
Dumping heap to /tmp/dump.hprof ...
Heap dump file created

转储文件通常与所使用的内存大小相同,因此建议在将其发送给开发人员之前压缩生成的文件。

XStream

Geoserver和GeoWebCache使用XStream来读写用于配置和REST API的XML。为了安全地完成这项工作,它需要一个Java类列表,这些类可以安全地在对象和XML之间进行转换。如果不在该列表上类被提供给XStream,它将生成错误 com.thoughtworks.xstream.security.ForbiddenClassException 。作为问题的特定类也应该包括在内。这可能是因为允许类的列表缺少一个类,这应该报告为错误,或者可能是因为扩展/插件没有将其类添加到列表中(最后,可能是有人试图执行“远程执行”攻击,这正是允许列表旨在防止的)。

可以通过设置系统属性来解决此问题 GEOSERVER_XSTREAM_WHITELIST 对于Geoserver或 GEOWEBCACHE_XSTREAM_WHITELIST 对于GeoWebCache,设置为以分号分隔的限定类名列表。类名称可以包括通配符 ? 对于单个字符, * 对于不包括分隔符的任意数量的字符 . ,以及 ** 用于任意数量的字符,包括分隔符。例如, org.example.blah.SomeClass; com.demonstration.*; ca.test.** 将允许,特定的类 org.example.blah.SomeClass ,紧接在包中的任何类 com.demonstration ,以及包中的任何类 ca.test 或它的任何后代套餐。

GEOSERVER_XSTREAM_WHITELISTGEOWEBCACHE_XSTREAM_WHITELIST 应仅在Geoserver、GWC或导致问题的扩展更新之前用作解决办法,因此请尽快向用户报告缺少的类。