Nginx基础理论

        Nginx最为最受欢迎的反向代理和负载均衡服务器,被广泛的应用于互联网项目中。这不仅仅是因为Nginx本身比较轻量,更多的是得益于Nginx的高性能特性,以及支持插件化开发,为此,很多开发者或者公司基于Nginx开发出了众多的高性能插件。使用者可以根据自身的需求来为Nginx指定某款插件以增强Nginx在某种特定场景下的功能或者提升Nginx在某种特定场景下的性能。

获取客户端信息

        客户信息主要指:客户真是IP、域名、协议、端口

        Nginx反向代理后,Servlet应用通过 request.getRemoteAddr() 取到的IP是Nginx的IP地址,并非客户端真实IP,通过 request.getRequestURL() 获取的域名、协议、端口都是Nginx访问Web应用时的域名、协议、端口,而非客户端浏览器地址栏上的真实域名、协议、端口

  存在的问题:

         例如在某一台IP为192.168.11.101的服务器上,Jetty或者Tomcat端口号为8080,Nginx端口号80,Nginx反向代理8080端口:

server {
listen 80;location / {proxy_pass http://127.0.0.1:8080; # 反向代理应用服务器HTTP地址}
}

在另一台机器上用浏览器打开http://192.168.11.100/test访问某个Servlet应用,获取客户端IP和URL:

System.out.println("RemoteAddr: " + request.getRemoteAddr());
System.out.println("URL: " + request.getRequestURL().toString());

控制台输出结果:

RemoteAddr: 127.0.0.1
URL: http://127.0.0.1:8080/test

        最终结果可以发现,程序获取到的客户端IP是Nginx的IP而非浏览器所在机器的IP,获取到的URL是Nginx配置的proxy_pass的URL组成的地址,而非浏览器地址栏上的真实地址。如果将ginx用作https服务器反向代理后端的http服务,那么 request.getRequestURL() 获取的URL是http前缀的而非https前缀,无法获取到浏览器地址栏的真实协议。如果此时将request.getRequestURL() 获取得到的URL用作拼接Redirect地址,就会出现跳转到错误的地址,这也是Nginx反向代理时经常出现的一个问题。

解决方案:

        由于Nginx是代理服务器,所有客户端请求都从Nginx转发到Tomcat,如果Nginx不把客户端真实IP、域名、协议、端口告诉Jetty/Tomcat,那么Tomcat应用永远不会知道这些信息,所以需要Nginx配置一些HTTP Header来将这些信息告诉被代理的Tomcat。

        Tomcat端,不能再获取直接和它连接的客户端(也就是Nginx)的信息,而是要从
Nginx传递过来的HTTP Header中获取客户端信息。

Nginx配置:

        我们需要在Nginx的配置文件nginx.conf中添加如下配置

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

参数含义解析:

  • Host 包含客户端真实的域名和端口号;
  • X-Forwarded-Proto 表示客户端真实的协议(http还是https);
  • X-Real-IP 表示客户端真实的IP;
  • X-Forwarded-For 这个Header和 X-Real-IP 类似,但它在多层代理时会包含真实客户端及中间每个代理服务器的IP。

重新使用 request.getRemoteAddr() 和 request.getRequestURL() 的输出结果:

RemoteAddr: 127.0.0.1
URL: http://192.168.11.100/test

        可以发现URL好像已经没问题了,但是IP还是本地的IP而非真实客户端IP。但是如果是用Nginx作为https服务器反向代理到http服务器,会发现浏览器地址栏是https前缀但是request.getRequestURL() 获取到的URL还是http前缀,也就是仅仅配置Nginx还不能彻底解决问

这个时候就需要通过JAVA代码解决以上问题:

/**** 获取客户端IP地址;这里通过了Nginx获取;X-Real-IP*/public static String getClientIP(HttpServletRequest request) {String fromSource = "X-Real-IP";String ip = request.getHeader("X-Real-IP");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("X-Forwarded-For");fromSource = "X-Forwarded-For";}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");fromSource = "Proxy-Client-IP";}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");fromSource = "WL-Proxy-Client-IP";}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();fromSource = "request.getRemoteAddr";}return ip;}

        这种方式虽然能够获取客户端的IP地址、问题也就解决了

Tomcat服务器配置:

        配置Tomcat的server.xml文件,在Host元素内最后加入:

<Valve className="org.apache.catalina.valves.RemoteIpValve" />

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/27501.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql都有哪些数据类型?

MySQL 支持多种数据类型&#xff0c;这些数据类型定义了存储在数据库中的数据的种类。以下是 MySQL 中常见的数据类型分类及其示例&#xff1a; 数值类型 整数类型 TINYINT&#xff1a;非常小的整数&#xff0c;带符号的范围是 -128 到 127&#xff0c;无符号的范围是 0 到 …

监控易监测对象及指标之:全面监控MongoDB 5数据库

随着企业数据量的持续增长&#xff0c;数据库的性能和稳定性对于保障业务连续性至关重要。MongoDB 5作为一款流行的NoSQL数据库&#xff0c;以其灵活的文档模型和强大的扩展能力&#xff0c;在各类业务场景中发挥着关键作用。 为了确保MongoDB 5数据库的稳定运行和高效性能&…

CCAA质量管理【学习笔记】​ 备考知识点笔记(一)

第一部分 质量管理体系相关标准 《质量管理体系基础考试大纲》中规定的考试内容&#xff1a; 3.1质量管理体系标准 a) 了解 ISO 9000 系列标准发展概况&#xff1b; b) 理 解 GB/T19000 标准中涉及的基本概念和质量管理原则&#xff1b; c) 理 解GB/T19000 标准中的部分…

论文阅读笔记:Instance-Aware Dynamic Neural Network Quantization

论文阅读笔记&#xff1a;Instance-Aware Dynamic Neural Network Quantization 1 背景2 创新点3 方法4 模块4.1 网络量化4.2 动态量化4.3 用于动态量化的位控制器4.4 优化 5 效果 论文&#xff1a;https://openaccess.thecvf.com/content/CVPR2022/papers/Liu_Instance-Aware_…

CDN绕过技术

DNS域名信息收集 简介 Dns域名信息的手机&#xff0c;需要收集域名对应IP&#xff0c;域名注册人&#xff0c;DNS记录&#xff0c;子域名等一系列与域名相关的信息。 Cdn技术简介 Cdn是一个内容分发网络&#xff0c;类似于dns服务器一样&#xff0c;用户发送数据直接发送到…

神经网络保存-导入

保存 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import gzip # fashion_mnisttf.keras.datasets.fashion_mnist # (train_images,train_labels),(test_images,test_labels)fashion_mnist.load_data()#数据在个人资源里面&#xff0c;放到该…

maven 下载jar包加载顺序

在 Maven 构建过程中&#xff0c;依赖的下载源取决于你的 pom.xml 文件中的 配置、settings.xml 文件中的 和 配置&#xff0c;以及你的 Nexus 仓库的设置。以下是决定 Maven 从哪个仓库下载依赖的关键点&#xff1a; 仓库配置优先级 项目 pom.xml 文件中的仓库配置&#xff…

联想电脑电池只能充到80%,就不在充电了,猛一看以为坏了,只是设置了养护模式。

现在电池管理模式有三种&#xff1a; 1&#xff09;常规 2&#xff09;养护 3&#xff09;快充 好久没有用联想的电脑了&#xff0c;猛一看&#xff0c;咱充到了80%不充了&#xff0c;难道电池是坏的&#xff1f;我们要如何设置才可以让其充电到100%呢&#xff1f; 右下角…

搜索文档的好助手

搜索文档的好助手 AnyTXT SearcherEverything AnyTXT Searcher 文本内容搜索 下载&#xff1a;AnyTXT Searcher Everything 它能够基于文件名快速定文件和文件夹位置 下载&#xff1a;Everything

LLM大语言模型算法特训,带你转型AI大语言模型算法工程师(完结)

LLM大语言模型算法 与AI大语言模型算法工程师的联系 LLM&#xff08;Large Language Model&#xff09;大语言模型是指像GPT这样的大型自然语言处理模型&#xff0c;而AI大语言模型算法工程师则是负责开发和优化这些模型的专业人士。它们之间的联系可以从以下几个方面来理解&a…

ROPgadget

他是一个常用的pwn工具. 首相看这一篇文章 什么是gadget&#xff0c;以及64位libc如何泄露的问题_libc特殊gadget收集-CSDN博客 之后看这一篇 (Pwn)CTF工具 ROPgadget 的安装与使用介绍_ropgadget --binary pwn strings information --strin-CSDN博客这个时候已经差不多了 …

Web前端网站设计案例:深入剖析创意与技术的完美融合

Web前端网站设计案例&#xff1a;深入剖析创意与技术的完美融合 在当今数字化时代&#xff0c;Web前端网站设计不仅关乎视觉美观&#xff0c;更涉及到用户体验、技术实现以及创意表达的融合。本文将通过四个方面、五个方面、六个方面和七个方面的详细阐述&#xff0c;带您深入…

江苏徐州存储服务器怎样进行搭建?

存储服务器是为特定目标所设计的&#xff0c;与普通的服务器之间是有着一定区别的&#xff0c;每个存储服务器的配置也是不同的&#xff0c;因为存储服务器是根据企业的自身需求来进行设置的&#xff0c;那么对于江苏徐州存储服务器我们应该怎样进行搭建呢&#xff1f; 对于存储…

Centos7.9使用kubeadm部署K8S集群

Centos7.9使用kubeadm部署K8S集群 使用kubeadm部署一个k8s集群&#xff0c;单master2worker节点。 1. 环境信息 操作系统&#xff1a;CentOS 7.9.2009内存: 2GBCPU: 2网络: 能够互访&#xff0c;能够访问互联网 hostnameip备注k8s-master192.168.0.51masterk8s-node1192.16…

【docker实战】使用代理的坑

在docker公共仓库被封禁的日子里&#xff0c;大多数人更喜欢使用镜像仓库代理源。 网上教程一大把&#xff0c;似乎不使用代理&#xff0c;就不会使用docker一样。 上图就是我设置的代理源镜像仓库。通常是设置/etc/docker/daemon.json这个文件实现的。 这样设置之后&#xff0…

【react】react 使用 Context 的简单示例

React的Context API是一种在组件树中传递数据的方法&#xff0c;它允许你将数据从顶层组件传递到底层组件&#xff0c;而无需手动在每个层级传递props。 目录 1 创建 Context2 提供 Context 值3 消费 Context 值4 不是子组件能通过Consumer获取吗&#xff1f; 1 创建 Context …

用python把docx批量转为pdf

为保证转换质量&#xff0c;本文的方法是通过脚本和com技术调用office自带的程序进行转换的&#xff0c;因此需要电脑已经装有office。如果希望不装office也能用&#xff0c;则需要研究OpenXML技术&#xff0c;后面实在闲的慌&#xff08;退休&#xff09;再搞。 安装所需库 …

Linux---​代码运行-程序的翻译过程

前言 我们平常用C/C语言写代码的时候&#xff0c;运行只是靠编译器&#xff0c;点一下运行按钮就会出现我们代码运行的结果&#xff0c;那我们的代码究竟是怎么得到最终结果的呢&#xff1f;还是非常值得我们去了解与学习的。 一、翻译过程 > 预处理 预处理功能主要包括宏…

智能合约与身份验证:区块链技术的创新应用

一、引言 区块链&#xff0c;一个近年来备受瞩目的技术名词&#xff0c;已经从最初的数字货币领域扩展到了众多行业。那么&#xff0c;究竟什么是区块链&#xff1f;它为何如此重要&#xff1f;本文将深入剖析区块链技术的原理、应用及未来发展。 二、区块链的基本概念 区块…

BeanFactory和FactoryBean的区别:

BeanFactory和FactoryBean的区别&#xff1a; BeanFactory和FactoryBean是Spring框架中两个不同的概念&#xff0c;它们的作用和使用方式有所不同。 1. BeanFactory&#xff08;普通Bean工厂/我们所用的都是Bean工厂创建的&#xff09;是Spring框架的核心接口之一&#xff0c…