我搜寻了互联网,试图找到可能遇到此问题但空手而归的人。因此,这里去:
我们有一个Java Web应用程序(基于Spring MVC 4)。它位于使用应用程序请求路由(ARR)v3充当负载平衡器/反向代理的Microsoft IIS的后面。
这种IIS与ARR执行负载平衡3个不同的环境(所有运行的 相同 的Java代码): dev.example.com,demo.example.com和qa.example.com。
dev.example.com
demo.example.com
qa.example.com
该应用程序通过SockJS和stompjs使用WebSockets向用户的浏览器提供通知,并且当应用程序服务器在Tomcat 7上时,这一切都正常运行。将qa.example.com环境升级到Tomcat 8后,WebSocket连接停止了工作-它回退到XHR POST要求。
我想强调的是,仅对qa应用程序服务器没有对IIS进行任何更改。
qa
这是来自dev环境(工作)的示例请求/响应:
dev
Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8 Cache-Control: no-cache Connection: Upgrade Cookie: <cookies snipped> Host: dev.example.com Origin: https://dev.example.com Pragma: no-cache Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits Sec-WebSocket-Key: E7aIek0X6qcO9PAl1n6w4Q== Sec-WebSocket-Version: 13 Upgrade: websocket User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36
响应
Cache-Control: no-cache, no-store, max-age=0, must-revalidate Connection: Upgrade Date: Thu, 22 Oct 2015 02:19:35 GMT Expires: 0 Pragma: no-cache Sec-WebSocket-Accept: dKYK05s4eP87iA20aSo/3ntOrPU= Server: Microsoft-IIS/8.0 Strict-Transport-Security: max-age=31536000 ; includeSubDomains Upgrade: Websocket X-Content-Type-Options: nosniff X-Frame-Options: DENY X-Powered-By: ARR/3.0 X-XSS-Protection: 1; mode=block
这是来自qa环境的示例请求/响应(中断):
Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8 Cache-Control: no-cache Connection: Upgrade Cookie: <cookies snipped> Host: qa.example.com Origin: https://qa.example.com Pragma: no-cache Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits Sec-WebSocket-Key: jTOIAT0+o35+Qi0ZWh2gyQ== Sec-WebSocket-Version: 13 Upgrade: websocket User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36
响应:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate Connection: Upgrade Date: Thu, 22 Oct 2015 02:18:30 GMT Expires: 0 Pragma: no-cache Sec-WebSocket-Accept: P+fEH8pvxcu3sEoO5fDizjSbwJc= Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15 Server: Microsoft-IIS/8.0 Strict-Transport-Security: max-age=31536000 ; includeSubDomains Upgrade: Websocket X-Content-Type-Options: nosniff X-Frame-Options: DENY X-Powered-By: ARR/3.0 X-XSS-Protection: 1; mode=block
唯一明显的区别是,qa响应中包含Sec-WebSocket-Extensions: permessage- deflate;client_max_window_bits=15标头,而dev响应中不包含标头。
Sec-WebSocket-Extensions: permessage- deflate;client_max_window_bits=15
我在IIS上打开了“失败的请求跟踪”来调试101响应,我看到有一些标头被IIS覆盖了-即Sec-WebSocket-Accept标头。
101
Sec-WebSocket-Accept
IIS还显示该请求正在创建502.5错误。我查了一下,发现了这一点:https : //support.microsoft.com/en- us/kb/943891这502.5就是“ WebSocket故障(ARR)”,仅此而已。不过,足够奇怪的是,Chrome开发工具显示它以101响应,就像应该…
502.5
我使用本地应用程序服务器(没有IIS的Tomcat 8)进行了所有尝试,并且websockets正常运行。Tomcat 7 + IIS + ARR + WebSockets可以正常工作。Tomcat 8 + IIS + ARR + WebSockets没有。
我的Tomcat 8的确切版本是8.0.28-但在Tomcat 8.0.26上却得到了相同的结果。
我的下一步是继续通过次要版本降级Tomcat 8,并查看是否有任何更改。如果发现任何问题,我将在这里更新。
这是我的本地服务器(没有IIS)的响应:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate Connection: upgrade Date: Thu, 22 Oct 2015 13:59:23 GMT Expires: 0 Pragma: no-cache Sec-WebSocket-Accept: 718HnPxHN8crYYzNGFjQf7w8O+Y= Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15 Server: Apache-Coyote/1.1 Strict-Transport-Security: max-age=31536000 ; includeSubDomains Upgrade: websocket X-Content-Type-Options: nosniff X-Frame-Options: DENY X-XSS-Protection: 1; mode=block
它看起来很像是中断的qa请求,但是效果很好。所以我想这Sec-WebSocket-Extensions是一条红鲱鱼。也Upgrade: websocket和Connection: upgrade我的本地服务器上较低的情况下,而这是Websocket与Upgrade当你把IIS在前面。
Sec-WebSocket-Extensions
Upgrade: websocket
Connection: upgrade
Websocket
Upgrade
Sec-WebSocket-Extensions也有尾随空间qa后,permessage-deflate;但当地没有。
permessage-deflate;
qa在Microsoft Edge(Windows 10)的环境中,所有功能都可以正常使用,但我还没有尝试过Internet Explorer 11,但是我不得不假设它也可以正常使用。OSX上的Firefox和Chrome无法正常工作。
来自Tomcat的请求在被IIS / ARR修改之前:
HTTP/1.1 101 Switching Protocols Server: Apache-Coyote/1.1 Upgrade: websocket Connection: upgrade Sec-WebSocket-Accept: luP49lroNK9qTdaNNnSCLXnxAWc= Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15 Date: Tue, 27 Oct 2015 21:10:48 GMT
我发现了解决方案,尽管它不如我希望的那样令人满意。
在我们的项目中,pom.xml我们有spring-core:4.2.5但是spring-websocket和spring- messaging是4.1.6。版本不匹配明显导致了一些问题。
pom.xml
spring-core:4.2.5
spring-websocket
spring- messaging
4.1.6
-Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true版本 不匹配 时在Tomcat启动选项中进行设置无效。在版本 相同时 设置JVM选项可以正常工作。
-Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true
101现在,响应中不包含该内容,permessage- deflate并且websockets可以通过IIS正确连接。我们的应用程序没有通过套接字发送大量数据,因此可以进行权衡。
permessage- deflate