当前位置: 首页 > news >正文

从nginx返回404来看http1.0和http1.1的区别

序言

    什么样的人可以称之为有智慧的人呢?如果下一个定义,你会如何来定义?

    所谓智慧,就是能区分自己能改变的部分,自己无法改变的部分,努力去做自己能改变的,而不要天天想着那些无法改变的东西,不然的话,就只能越来越消极了,消极的原因大部分也在于总是关注于自己无法改变的现实。

nginx返回404问题排查

    背景

    大部分的人在看到nginx返回404的时候,要么就是请求了一个不存在的资源或者接口,要么就是location写的有问题,基本不会想到是协议导致的。

    架构

    现在的应用程序都讲究前后端分离,分离不完整的时候,就会进行修改架构,在修改之前的架构如下:

cb71359aaf709d06a8d1b283d8f6220f.png

    为了从统一入口进来,从而将架构修改为如下:

841c781d38c44087daf3475b56b6ff44.png

    修改之后的好处主要是能减少客户端能接触的东西,从而减少暴露面,当有攻击的时候,排查或者封杀的面不会很多。

    1 前端nginx进行重新配置

    在前端nginx上面,其实只要增加一段location的配置即可,从而使用了极简的配置:

upstream backend {server   192.168.1.1;server   192.168.1.2;
}
location  /api/{proxy_pass http://backend;proxy_set_header X-Real_IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

    在添加完成配置之后,将nginx进行reaload,让配置生效,再次进行验证请求之后,发现后端请求的接口全部变成了404.

    此时的你,该如何去解决这个问题?

    对,应该第一时刻进行回滚备份的配置,先让生产跑起来,再来解决问题。

    2 查看前端和后端的日志

    变更导致的问题,要么看配置是不是有问题,要么看日志查查问题出现的点在哪里。

    在查看nginx的accesslog的时候,重要的看请求发到了哪个后端,404是不是后端返回的,如果404是nginx直接返回的,说明还没到达后端,如果是后端的返回的,那么就要看后端nginx的日志了。

    在此处的问题中,查看前端nginx日志的时候,发现是后端nginx返回的404,因为upsteam_status 为404,而且能找到对应的upsteam server的ip,从而到对应的后端nginx上去查看日志。

    但是,非常奇怪的是,在后端nginx上面未看到任何请求日志,在后端nginx上面,使用的是vhost的配置,也就是虚拟主机。

    那么现在可以得到一个初步结论:

1 404 的确是后端nginx返回的
2 后端nginx上面没找到对应的访问日志

    3 可能出现问题的地方

    根据如上的结论,那么哪些地方可能出现问题呢?

    首先再看了一眼加了location配置的地方,比平时的配置少一些东西:

proxy_set_header Host $host;
proxy_set_header Connection "";
proxy_http_version 1.1;

    在后端的nginx对应的server段的配置的日志路径上面,没找到对应的日志信息,但是前端的nginx返回中说明是后端nginx返回的,从而找到对应的默认主机,也就是default server中,发现默认配置没有,那么就找到在vhost中第一个主机段,查看它的日志,发现了请求。

    从而问题已经找到,因为在nginx的默认配置中,如果不指定http协议版本的话,那么默认是1.0版本,而对于http 1.0版本来说,默认是不会加上host头部的,从而当请求到后端nginx的时候,找不到对应server name进行处理,从而走了默认的server段进行处理,从而导致了对应的虚拟主机没有日志,而在默认的虚拟主机中找到了对应的访问日志。

    从而再将host头部进行设置,然后切换,发现访问正常。

    那么再尝试一下第二种方案,不加host后端,而指定http协议为1.1,因为http1.1协议默认会传输host头部,从而无需显示指定,发现也是ok的。

    最后再把这三个头部加上,主要是为了让两个nginx之间保持长连接,从而减少三次握手的时间,当然upsteam之中,也要将keepalive指令打开,不然也是不能激活长连接的,因为nginx的默认值如下:

Syntax:  keepalive connections;
Default:  —
Context:  upstream

6770a3b39a0427eff32d850f3f354ab6.png

风言风语

   一个东西,使用的多了,就能遇到各种各样的问题,而在一些资料上看到的东西,你会发现那都是基础中的基础,解决不了任何问题,但是却是解决问题的根基,简单的报错,但是中间就充斥着各种可能得组合原因。就像做数学,基础都是1+1,然后来个3+2,都是同样的道理。

    知道并不代表能灵活运行,能猜到可能的原因和解法,对比法也是一个比较好的方法。

    努力的方向也是自己能改变的东西,也是自己能掌控的东西,如果努力的方向都是不能改变的,不可控的,那么这种努力也将是一种徒劳。

http://www.lryc.cn/news/395151.html

相关文章:

  • MySQL 代理层:ProxySQL
  • 异步主从复制
  • 论文解析——Full Stack Optimization of Transformer Inference: a Survey
  • selenium处理cookie问题实战
  • (十五)GLM库对矩阵操作
  • android中activity与fragment之间的各种跳转
  • 动态规划算法-以中学排课管理系统为例
  • 本安防爆手机:危险环境下的安全通信解决方案
  • 算法学习笔记(8)-动态规划基础篇
  • 数据库常见问题(持续更新)
  • 定个小目标之刷LeetCode热题(40)
  • Linux--线程(概念篇)
  • Mojo: 轻量级Perl框架的魔力
  • Python 游戏服务器架构优化
  • 13 学习总结:指针 · 其一
  • golang 项目打包部署环境变量设置
  • 【Linux进程】进程优先级 Linux 2.6内核进程的调度
  • Linux中的粘滞位及mysql日期函数
  • BP神经网络的实践经验
  • PCL 点云FPFH特征描述子
  • 基于golang的文章信息抓取
  • 【手撕数据结构】卸甲时/空间复杂度
  • 消防认证-防火窗
  • C++进阶-二叉树进阶(二叉搜索树)
  • 【Unity小知识】UnityEngine.UI程序集丢失的问题
  • CentOS 离线安装部署 MySQL 8详细教程
  • 云计算【第一阶段(28)】DNS域名解析服务
  • pygame 音乐粒子特效
  • Leetcode 295.数据流的中位数
  • A59 STM32_HAL库函数 之 TIM扩展驱动 -- A -- 所有函数的介绍及使用