SpringBoot- 技术专题 -Websocket+Nginx出现404问题

InfoQ 2020-11-06 01:15:35
springboot- springboot 技术 专题 websocket+nginx


{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"问题描述:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 使用websocket往商家管理系统发送消息。在本地测试没有任何问题,但是部署到centos服务器上之后一直报错404。总结了网上很多解决方法都不行,网上讨论的都是说tomcat版本太低,因为websocket需要tomcat7.0以上才支持。"}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"解决思路:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 排除了tomcat问题,jdk版本也是1.8+,websocket部署到服务器上还是404,网上还有人说是tomcat的jar包和项目jar冲突,可是我springboot项目使用的内嵌tomcat,于是我利用Maven Helper(非常好用的idea插件)查看了下依赖发现并没有冲突。卡在这里很久,我特地看了下websocket请求格式:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Websocket握手格式:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"GET /chat HTTP/1.1\nHost: server.example.com\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\nSec-WebSocket-Protocol: chat, superchat\nSec-WebSocket-Version: 13\nOrigin: http://example.com12345678"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这请求类似http协议,里面多了陌生的内容是:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"Upgrade: websocket\nConnection: Upgrade12"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 当时一脸懵逼,这是什么玩意啊?然后我就百度了下,原来这个就是Websocket的核心,他会告诉Apache、Nginx等服务器我发起的是websocket请求,不是http!下面的三个参数Sec-WebSocket-Key、Sec-WebSocket-Protocol、Sec-WebSocket-Version作用大概就是验证请求确实是websocket,同时指定协议版本吧。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 这时候我恍然大悟!我的项目使用了nginx做了转发,那么会不会是因为我没有配置nginx响应websocket请求呢?答案是肯定的!"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"配置nginx反向代理响应webSocket请求"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要在代理的请求配置中加入下面的配置:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"proxy_set_header Upgrade $http_upgrade;\nproxy_set_header Connection \"upgrade\";12"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"nginx配置如下:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"server {\n listen 80;\n server_name localhost;\n #charset koi8-r;\n\n location / {\n root /usr/java/myproject/sell;\n index index.html index.htm;\n }\n\n location /sell/ {\n proxy_pass http://127.0.0.1:8081/sell/;\n }\n\nlocation /sell/webSocket {\n proxy_pass http://127.0.0.1:8081/sell/webSocket; \n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"upgrade\";\n}12345678910111213141516171819"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这段配置就是把所有的/sell下的请求转到8081端口处理,把/sell/webSocket请求转发到指定的请求接口,发现404错误消失,webSocket服务也可以访问到。但是出现了一个新的问题就是,webSocket连接后没有保持连接,大约一分钟之后就会断开,原因是因为在第一次请求后到第二次请求到来的时间超过了默认的最大时间,超时了。这里提供一个解决思路:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要配置的三个核心参数:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"proxy_connect_timeout 4s; \nproxy_read_timeout 7200s; \nproxy_send_timeout 12s; 123"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"proxy_read_timeout是服务器对连接等待的最大时间,也就是说,当你webSocket使用nginx转发的时候,用上面的配置来说,如果72000秒内没有通讯,依然是会断开的,你可以按照需求来设定。"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如说,我这里设置了7200s(2小时),那么如果我2小时内有通讯,或者2小时内有心跳的话,是可以保持连接不中断的。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我这里之所以这么设置,是考虑到了具体的业务情况,2小时比较合适。最终的配置如下:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"server {\n listen 80;\n server_name localhost;\n #charset koi8-r;\n\n location / {\n root /usr/java/myproject/sell;\n index index.html index.htm;\n }\n\n location /sell/ {\n proxy_pass http://127.0.0.1:8081/sell/;\n }\n\nlocation /sell/webSocket {\n proxy_pass http://127.0.0.1:8081/sell/webSocket; \n proxy_connect_timeout 4s; \n proxy_read_timeout 7200s; \n proxy_send_timeout 12s; \n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"upgrade\";\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/7cba4c63789de88120a0fe113?utm_source=rss&utm_medium=article

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云