记一次线上websocket返回400问题排查
现象
生产环境websocket无法正常连接,服务端返回400 bad request,开发及测试环境均正常。

抓包排查
src:nginx服务器 172.16.177.193
dst:imp应用服务器 172.16.177.218

问题定位
观察到header中的host值带有下划线,在一些中间件(如kafka、hadoop)中,对host中的特殊字符也有限制。由此猜测是header问题。
经排查,此header来自nginx的upstream

解决方案1
修改nginx的upstream配置,去除下划线
解决方案2
既然upstream中用了下划线,为何普通的http请求正常,而websocket则返回400呢?
再看正常的http请求的抓包
src: nginx服务器 172.31.47.151
dst: imp应用服务器 172.31.47.153

可见,header中的host,被转发到了目标服务器,而此host并没有下划线,正常请求。
所以,如果不修改nginx中的upstream下划线的配置,其实还可以在server中的websocket 对应的location中,添加参数,以便转发原始请求的host
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|

配置后的抓包如下

请求正常
原因探讨
带有下划线的host,为何会被服务端返回400?从上述排查过程可知,应是tomcat返回的。
这一切要从一个RFC协议规范说起
RFC-1034 是一个关于DNS及域名基础的标准。在「3.5 Preferred name syntax」中,有提及主机名的格式规范:由字母开头,字母或数字结尾,中间包含字母、数字或横杆

可见,RFC-1034标准中下划线并不被允许。
而Tomcat在一次8.x的升级中遵循该标准对host做了此校验,详见链接
org.apache.coyote.AbstractProcessor#parseHost
org.apache.tomcat.util.http.parser.Host#parse(java.io.Reader)

总结
在我们日常配置host参数时,都尽量避免使用下划线。包括在/etc/hosts下进行的配置,有时在集群环境中为了方便管理,会配置host,此时也应注意避免使用下划线。因为中间件可能也遵循了RTC规范。
延伸阅读
如果大家阅读了上述规范,可能会有疑问:为何网易163可以是数字开头?大家可以先去了解下域名的解析过程。
此处科普几个基本概念。
- domain name is the identifier of a resource in a DNS database
- label is the part of a domain name in between dots
- hostname is a special type of domain name which identifies Internet hosts
域名是在dns库中的唯一标识,label是域名中以「.」分隔的单元,hostname是对于一个地址的特殊域名映射。
在1989年的RFC-1101中的「3.1 Network name syntax」定义了网络名词的DNS编码规范。允许数字开头,只要不与十进制八位字节形式的ip地址冲突。
在1997年的RFC-2181中「11 Name syntax」对域名语法作了澄清,下划线不应被DNS服务所拒绝。
而在近年的一次CA/B论坛里,众多大厂发起投票,禁止在域名中使用下划线,否则SSL证书将不能正常申请使用。
有兴趣的朋友可以尝试搭建一个网站并作域名映射。可以确定的是,做域名映射时,因为是hostname,A和MX记录是不能带下划线的。CNAME记录由于针对的是域名,是否支持则取决于你的DNS服务商了。
记一次线上websocket返回400问题排查的更多相关文章
- 记一次线上bug排查-quartz线程调度相关
记一次线上bug排查,与各位共同探讨. 概述:使用quartz做的定时任务,正式生产环境有个任务延迟了1小时之久才触发.在这一小时里各种排查找不出问题,直到延迟时间结束了,该任务才珊珊触发.原因主要就 ...
- 解Bug之路-记一次线上请求偶尔变慢的排查
解Bug之路-记一次线上请求偶尔变慢的排查 前言 最近解决了个比较棘手的问题,由于排查过程挺有意思,于是就以此为素材写出了本篇文章. Bug现场 这是一个偶发的性能问题.在每天几百万比交易请求中,平均 ...
- Linux(2)---记录一次线上服务 CPU 100%的排查过程
Linux(2)---记录一次线上服务 CPU 100%的排查过程 当时产生CPU飙升接近100%的原因是因为项目中的websocket时时断开又重连导致CPU飙升接近100% .如何排查的呢 是通过 ...
- 线上CPU飙升100%问题排查
本文转载自线上CPU飙升100%问题排查 引子 对于互联网公司,线上CPU飙升的问题很常见(例如某个活动开始,流量突然飙升时),按照本文的步骤排查,基本1分钟即可搞定!特此整理排查方法一篇,供大家参考 ...
- 一次线上CPU高的问题排查实践
一次线上CPU高的问题排查实践 前言 近期某一天上班一开电脑,就收到了运维警报,有两台服务CPU负载很高,同时收到一线同事反馈 系统访问速度非常慢,几乎无响应. 一个美好的早晨,最怕什么就来什么.只好 ...
- 线上Redis偶发性链接失败排查记
问题过程 输入法业务于12月12日上线了词库接受业务,对部分用户根据用户uuid判断进行回传,在12月17日早上8点多开始出现大量的php报错(Redis went away),报错导致了大量的链接积 ...
- 记一次线上Kafka消息堆积踩坑总结
2018年05月31日 13:26:59 xiaoguozi0218 阅读数:2018更多 个人分类: 大数据 年后上线的系统,与其他业务系统的通信方式采用了第三代消息系统中间件Kafka.由于是 ...
- 记一次线上由nginx upstream keepalive与http协议"协作"引起的接口报错率飙高事件
年前接到个任务,说要解决线上一些手机客户端接口报错率很高的问题.拿到了监控邮件,粗略一看,各种50%+的错误率,简直触目惊心.这种疑难杂症解决起来还是挺好玩的,于是撸起袖子action. 最终的结果虽 ...
- 记一次线上 OOM 和性能优化
大家好,我是鸭血粉丝(大家会亲切的喊我 「阿粉」),是一位喜欢吃鸭血粉丝的程序员,回想起之前线上出现 OOM 的场景,毕竟当时是第一次遇到这么 紧脏 的大事,要好好记录下来. 1 事情回顾 在某次周五 ...
随机推荐
- Python入门随记(4)
在涉及一些实际问题,会碰到概率论等相关领域的知识,自然少不了矩阵运算,以下是Python中关于矩阵的简单操作: 1.常用库numpy import numpy as np 2.随机生成矩阵 a=np. ...
- 用 EXISTS 或 NOT EXISTS 用法
项目中遇到这么个情况: t1表 和 t2表 都是150w条数据,600M的样子,都不算大. 但是这样一句查询 ↓ select * from t1 where phone not in (selec ...
- 消息中间件-RabbitMq相关概念及原理介绍【图文并茂】
消息中间件 消息中间件的作用 解耦:消息中间件在服务之间插入了一个隐含的.基于数据的接口层.两边的服务处理过程都要实现这一接口,这允许我们独立的扩展或修改两边的处理过程,只要确保他们遵守相同的规范约束 ...
- [SPDK/NVMe存储技术分析]004 - SSD设备的发现
源代码及NVMe协议版本 SPDK : spdk-17.07.1 DPDK : dpdk-17.08 NVMe Spec: 1.2.1 基本分析方法 01 - 到官网http://www.spdk.i ...
- vue学习过程总结(02)- 网上开源项目vue-element-admin的启动
1.功能丰富的项目:https://github.com/PanJiaChen/vue-element-admin.git 因为我配置的时候,遇到许多的问题,用了一天半才启动的,所以安着他文档一步一步 ...
- Cobalt Strike的使用
0x00 Cobalt Strike简介 Cobalt Strike 一款以metasploit为基础的GUI的框架式渗透测试工具,集成了端口转发.服务扫描,自动化溢出,多模式端口监听, ...
- tomcat启动 ssm项目出现乱码的解决
0.乱码产生原因:编码和解码的方式是不同 1.出现乱码的解决方式[推荐]: 在tomcat 的配置文件web.xml 中添加上请求编码过滤器: <!-- 请求编码过滤器 --> <f ...
- Ribbon和Feign的区别?
1.Ribbon都是调用其他服务的,但方式不同.2.启动类注解不同,Ribbon是@RibbonClient feign的是@EnableFeignClients3.服务指定的位置不同,Ribbon是 ...
- 什么是 Mybatis?
1.Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时 只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动.创建连接.创建 statement 等繁杂的过程. ...
- Eureka和Zookeeper区别?
(1)Eureka取CAP的AP,注重可用性,Zookeeper取CAP的CP注重一致性. (2)Zookeeper在选举期间注册服务瘫痪,虽然服务最终会恢复,但选举期间不可用. (3)eureka的 ...