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

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" />

相关文章:

Nginx基础理论

Nginx最为最受欢迎的反向代理和负载均衡服务器&#xff0c;被广泛的应用于互联网项目中。这不仅仅是因为Nginx本身比较轻量&#xff0c;更多的是得益于Nginx的高性能特性&#xff0c;以及支持插件化开发&#xff0c;为此&#xff0c;很多开发者或者公司基于Nginx开发出了众多的…...

【QT5】<应用> 小游戏:贪吃蛇

文章目录 一、项目要求 二、需求分析 三、实现效果 四、代码 一、项目要求 【1】主要实现&#xff1a;游戏界面存在一条蛇&#x1f40d;&#xff0c;使用键盘wsad或者↑↓←→键盘可以控制蛇的行走方向。同时界面中会随机出现食物&#xff0c;蛇可以吃食物&#xff0c;然后…...

【Webpack】使用 Webpack 构建 Vue3+TS 项目

构建项目目录 tsc --init npm init -yshim.d.ts 文件是一个类型声明文件&#xff0c;用于告诉 TypeScript 编译器如何处理 Vue 的单文件组件&#xff08;SFC&#xff09;和其他自定义模块。为 Vue 的单文件组件和其他非 TypeScript 模块提供类型信息&#xff0c;以便在 TypeScr…...

数据防泄漏的六个步骤|数据防泄漏软件有哪些

在当前复杂多变的网络安全环境下&#xff0c;数据防泄漏软件成为了企业信息安全架构中不可或缺的一环。下面以安企神软件为例&#xff0c;告诉你怎么防止数据泄露&#xff0c;以及好用的防泄露软件。 1. 安企神软件 安企神软件是当前市场上备受推崇的企业级数据防泄漏解决方案…...

SpringCloud 网关Gateway配置并使用

目录 1 什么是网关&#xff1f; 2 Gateway的使用 2.1 在其pom文件中引入依赖 2.2 然后gateway配置文件中配置信息 2.3 启动网关微服务 3 网关处理流程 4 前端-网关-微服务-微服务间实现信息共享传递 1 什么是网关&#xff1f; 网关&#xff1a;就是网络的关口&#xff…...

MySQl基础----Linux下搭建mysql软件及登录和基本使用(附实操图超简单一看就会)

绪论​ 涓滴之水可磨损大石&#xff0c;不是由于他力量强大&#xff0c;而是由于昼夜不舍地滴坠。 只有勤奋不懈地努力&#xff0c;才能够获得那些技巧。 ——贝多芬。新开MySQL篇章&#xff0c;本章非常基础包括如何在Linux上搭建&#xff08;当然上面的SQL语句你在其他能执行…...

PostgreSQL17优化器改进(4)允许UNION(没有ALL)使用MergeAppend

PostgreSQL17优化器改进(4)允许UNION(没有ALL)使用MergeAppend UNION存在的问题 到PostgreSQL16.3版本为止&#xff0c;UNION执行计划通常不是最优的&#xff0c;优化器有两种处理方法&#xff1a; 优化器只考虑使用Append节点并通过使用Hash Aggregate&#xff0c;Append -…...

SSM 基于大数据技术的创业推荐系统-计算机毕业设计源码02979

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…...

基于WPF技术的换热站智能监控系统03--实现左侧加载动画

1、左侧布局规划 左侧分5行&#xff0c;每行的高度通过height属性来指定&#xff0c;1.2*表示占1.2倍的宽度 2、创建用户控件 在WPF中想要进行个性化处理&#xff0c;主要可以通过三个方面来实现&#xff1a;控件模板&#xff08;控件模板、数据模板、数据容器模板&#xff09…...

4D毫米波雷达技术及发展

文章目录 前言一、4D毫米波雷达是什么&#xff1f;二、毫米波雷达是什么&#xff1f;毫米波雷达的基本原理多普勒效应 前言 现阶段自动驾驶技术中&#xff0c;主要用到的传感器有摄像头、激光雷达和毫米波雷达。 摄像头的光谱从可见光到红外光谱&#xff0c;是最接近人眼的传感…...

请解释Java Web应用的开发流程,包括前后端分离和交互方式。请解释Java中的锁分离技术,并讨论其在提高并发性能方面的作用。

请解释Java Web应用的开发流程&#xff0c;包括前后端分离和交互方式。 Java Web应用的开发流程是一个涵盖多个阶段的过程&#xff0c;这些阶段从需求分析开始&#xff0c;经过设计、编码、测试&#xff0c;最终到部署和维护。在这个过程中&#xff0c;前后端分离成为现代Web应…...

selenium使用已经打开的浏览器

Selenium 本身不支持直接连接到一个已经打开的浏览器页面。Selenium 启动的浏览器实例是一个全新的会话&#xff0c;它与手动打开的浏览器页面是分开的。但是&#xff0c;有一些变通的方法可以实现类似的效果。 一种方法是通过附加代理连接到已经打开的浏览器。下面是如何实现…...

Redis: 深入解析高性能内存数据库的实现原理

一、Redis简介 Redis是一种基于内存的键值存储数据库&#xff0c;支持丰富的数据类型&#xff0c;如字符串、列表、集合、有序集合和哈希表。它不仅具有极高的性能&#xff0c;还支持数据持久化、主从复制和分布式架构&#xff0c;使其在各种应用场景中表现出色。 1.1 Redis的…...

使用 Python进行自动备份文件

文件备份对数据保护至关重要&#xff0c;让我们使用 shutil 模块创建一个简单的备份脚本 这段代码的作用就是将指定源目录中的所有文件备份到目标备份目录中&#xff0c;并在备份目录中创建带有时间戳的子目录&#xff0c;通过定期运行这段代码&#xff0c;可以实现自动备份文…...

02_01_SpringMVC初识

一、回顾MVC三层架构 1、什么是MVC三层 MVC是 模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;、控制器&#xff08;Controller&#xff09;的简写&#xff0c;是一种软件设计规范。主要作用是降低视图与业务逻辑之间的双向耦合&#xff0c;它不是一种…...

Python学习打卡:day04

day4 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day428、while 循环的嵌套应用29、while 循环案例 — 九九乘法表补充知识示例&#xff1a;九九乘法表 30、for 循环基本语法while 和 for 循环对比f…...

gitlab问题记录

You wont be able to pull or push project code via SSH until you add an SSH key to you 解决方案&#xff1a;https://blog.csdn.net/gufenchen/article/details/95663284...

OpenCV练习(1)签名修复

1.目的 在学校的学习过程中&#xff0c;需要递交许多材料&#xff0c;且每份材料上都需要对应负责人签名&#xff0c;有时候找别人要签名&#xff0c;然后自己粘贴的话&#xff0c;会出现签名模糊&#xff0c;背景不是纯白透明。为此以word中的“颜色校正”功能为参照&#xf…...

软设之系统测试之测试的基本概念及分类

测试的基本概念 尽早&#xff0c;不断地进行测试 程序员避免测试自己设计的程序 既要选择有效&#xff0c;合理的数据&#xff0c;也要选择无效&#xff0c;不合理的数据 修改后应进行回归测试 尚未发现的错误数量与该程序已发现错误其他成正比。 动态测试 黑盒测试(测试…...

Python学习打卡:day06

day6 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day648、函数综合案例49、数据容器入门50、列表的定义语法51、列表的下标索引1、列表的下标&#xff08;索引&#xff09;2、列表的下标&#xff08…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)

+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...