版权声明
- 本文原创作者:谷哥的小弟
- 作者博客地址:http://blog.csdn.net/lfdfhl

服务器运行环境
很多初级开发工程师最初在Windows环境中学习数据库和Java开发。例如,在Windows中安装MySQL以后,可以直接使用Navicat连接数据库。由于MySQL服务端程序和Navicat运行在同一台计算机中,IP地址、端口、监听地址以及网络访问控制等内容通常不容易被注意到。
当MySQL、Redis、RabbitMQ等软件运行在Linux服务器中,而开发工具或业务程序运行在其他计算机中时,软件之间的访问开始依赖网络。此时,需要明确各个程序运行的位置,以及客户端、服务端、IP地址、端口、服务监听和端口开放之间的关系。
阿里云ECS是一种云服务器实例,可以将其视为一台通过网络使用的远程计算机。Ubuntu是运行在ECS中的操作系统,MySQL Server、Redis Server、RabbitMQ、Nginx等软件则运行在Ubuntu中。
例如,一台ECS中可以同时运行以下软件:
text
Ubuntu
MySQL Server
Redis Server
RabbitMQ
Nginx
Spring Boot应用
阿里云ECS属于服务器主机,MySQL Server、Redis Server和RabbitMQ属于运行在服务器主机中的服务端程序。二者属于不同层次。
开发人员使用的Windows电脑则是另一台独立的计算机。Navicat、浏览器、IDE等软件通常运行在Windows电脑中。
一个常见的开发环境如下:
text
Windows电脑
Navicat
浏览器
IDE
阿里云ECS
Ubuntu
MySQL Server
Redis Server
RabbitMQ
Nginx
Spring Boot应用
软件运行在哪台计算机中,将直接影响访问时使用的地址,也会影响相应端口是否需要允许外部访问。
客户端和服务端
网络通信通常由发起访问的一方连接提供服务的一方。
以MySQL为例,MySQL Server是数据库服务端程序。Ubuntu中运行的mysqld进程用于管理数据库数据,并接收客户端发送的数据库访问请求。
Navicat属于MySQL客户端。开发人员在Navicat中查询数据、修改数据或管理数据库时,Navicat先连接MySQL Server,再向MySQL Server发送相应请求。
MySQL安装后提供的mysql命令同样属于客户端程序。例如,在Linux服务器中执行:
bash
root@iZuf6b6jn2nrwa2q1kdxlcZ:~# mysql -u root
该命令启动MySQL命令行客户端,并使用root账户连接MySQL Server。
Redis具有类似的结构。redis-server运行Redis服务,redis-cli用于连接Redis并执行命令。
RabbitMQ提供消息服务。Spring Boot应用访问RabbitMQ时,由Spring Boot主动建立连接,并通过RabbitMQ提供的服务发送或接收消息。
浏览器访问Spring Boot提供的Web接口时,Spring Boot接收浏览器发送的请求;Spring Boot访问MySQL、Redis或RabbitMQ时,则主动连接这些服务。
分析软件之间的网络访问时,应先确定访问从哪个程序发起,以及目标服务运行在哪台计算机中。
本机访问和远程访问
客户端和服务端程序运行在同一台计算机中时,可以进行本机访问。
假设Spring Boot和MySQL都直接运行在同一台Linux服务器中,Spring Boot访问MySQL时,两个程序之间的通信发生在这台服务器内部,不需要经过互联网。
Redis和RabbitMQ也是相同情况。如果Spring Boot、Redis和RabbitMQ都运行在同一台Linux服务器中,Spring Boot可以直接访问服务器本机中的Redis和RabbitMQ。
客户端和服务端程序运行在不同计算机中时,则需要通过网络进行远程访问。
例如,Navicat运行在Windows电脑中,而MySQL Server运行在阿里云ECS中。Navicat连接MySQL时,需要通过网络访问ECS中的MySQL服务。
如果Redis Server运行在ECS中,而Redis客户端运行在Windows电脑中,同样属于远程访问。
因此,本机访问和远程访问的区别主要取决于通信双方是否运行在同一台计算机中。
IP地址和本机地址
远程访问需要确定目标主机。IP地址用于标识网络中的主机,客户端访问另一台计算机时,需要使用能够到达目标主机的IP地址。
阿里云ECS可以具有公网IP。Windows电脑通过互联网直接访问ECS时,可以使用ECS的公网IP。
同一台计算机内部的程序通信时,通常可以使用本机回环地址。
IPv4中常用的本机回环地址为:
text
127.0.0.1
127.0.0.1表示正在使用该地址的计算机自身。
如果Windows中的程序访问:
text
127.0.0.1
访问的是Windows电脑自身。
如果Linux服务器中的程序访问:
text
127.0.0.1
访问的是Linux服务器自身。
例如,Windows中的Navicat连接:
text
127.0.0.1:3306
表示尝试访问Windows电脑自己的3306端口,并不是访问远程ECS中的MySQL。
如果Spring Boot和MySQL都运行在同一台Linux服务器中,Spring Boot连接:
text
127.0.0.1:3306
表示访问当前Linux服务器中的MySQL。
localhost通常也表示当前计算机。为了明确表示IPv4本机地址,本文主要使用127.0.0.1进行说明。
端口
一台服务器可以同时提供多种网络服务。客户端确定目标服务器以后,还需要确定希望访问服务器中的哪项服务。
端口号用于区分一台主机上提供的不同网络服务。
常见服务使用的端口如下。
| 服务 | 常用端口 | 主要用途 |
|---|---|---|
| MySQL | 3306 | 数据库客户端连接 |
| Redis | 6379 | Redis客户端连接 |
| RabbitMQ | 5672 | 应用程序消息通信 |
| RabbitMQ Management | 15672 | Web管理界面 |
| Nginx HTTP | 80 | HTTP访问 |
| Nginx HTTPS | 443 | HTTPS访问 |
假设一台服务器的IP地址为:
text
192.168.1.100
客户端访问:
text
192.168.1.100:3306
表示连接IP地址为192.168.1.100的主机,并访问该主机的3306端口。如果MySQL正在该端口提供服务,客户端访问的就是MySQL。
访问:
text
192.168.1.100:6379
表示访问同一台主机的6379端口。如果Redis正在使用该端口,客户端访问的就是Redis。
因此,IP地址用于确定目标主机,端口号用于进一步确定目标主机上的网络服务。
服务监听
MySQL、Redis、RabbitMQ等服务启动后,需要在指定的本地地址和端口上等待客户端建立网络连接。这种等待连接的状态称为监听。
例如,MySQL可能监听:
text
127.0.0.1:3306
其中,127.0.0.1表示当前主机自身,3306是MySQL客户端通常使用的端口。
该监听状态表示MySQL正在当前主机的本机地址上等待3306端口的连接。
Redis可能监听:
text
127.0.0.1:6379
表示Redis正在当前主机的本机地址上等待6379端口的客户端连接。
RabbitMQ通常使用5672端口接收应用程序连接。
Linux中可以使用ss命令查看当前正在监听的TCP端口:
bash
root@iZuf6b6jn2nrwa2q1kdxlcZ:~# ss -lntp
MySQL、Redis和RabbitMQ等软件通常通过TCP建立客户端连接。客户端使用目标IP地址和端口连接相应服务。
ss -lntp的结果可以显示正在监听的本地地址、端口以及对应进程。
监听地址
监听地址决定服务通过当前主机的哪些IPv4地址接收连接。
MySQL可以通过bind-address配置监听地址。例如:
text
bind-address=127.0.0.1
127.0.0.1是本机回环地址。采用该配置时,MySQL只接受当前服务器本机发起的IPv4连接。
如果Spring Boot和MySQL运行在同一台Linux服务器中,Spring Boot仍然可以通过:
text
127.0.0.1:3306
访问MySQL。
Windows中的Navicat则无法使用ECS公网IP直接连接这个MySQL服务,因为MySQL此时只在本机地址上接收连接。
MySQL还可以配置为:
text
bind-address=0.0.0.0
在服务监听配置中,0.0.0.0表示当前主机上的所有本地IPv4地址。采用该配置后,MySQL可以通过服务器的IPv4地址接收连接,为其他计算机访问MySQL提供了必要条件。
Redis中的bind配置具有类似作用。例如:
text
bind 127.0.0.1 -::1
表示Redis监听本机回环地址。
配置为:
text
bind 0.0.0.0
后,Redis可以通过当前主机的IPv4地址接收连接。
服务监听0.0.0.0只表示服务本身具备通过当前主机IPv4地址接收连接的条件。远程客户端能否真正建立连接,还取决于安全组、防火墙和网络通信状态。
端口开放
在服务器使用场景中,"开放端口"通常表示允许服务器外部的计算机通过网络访问某个端口。
对于阿里云ECS,是否允许外部访问某个端口,通常与安全组入方向规则有关。如果Linux服务器启用了防火墙,防火墙规则也可能限制相应端口的访问。
服务监听端口和开放端口属于不同概念。
MySQL监听3306端口,表示MySQL服务正在等待3306端口的客户端连接。
安全组允许3306端口入方向访问,表示阿里云允许符合规则的外部网络流量进入ECS的3306端口。
只有MySQL自身能够接收连接,并且外部网络访问没有被安全组、防火墙等规则阻止,远程客户端才可能建立连接。
因此,安装MySQL、Redis或RabbitMQ以后,并不需要因为这些软件使用了3306、6379或5672端口,就自动允许这些端口从公网访问。
无需开放公网端口的场景
如果访问某项服务的程序和该服务运行在同一台Linux服务器中,通常没有必要允许相应端口从公网访问。
Spring Boot访问MySQL
Spring Boot和MySQL都运行在同一台Linux服务器中时,Spring Boot可以连接:
text
127.0.0.1:3306
两个程序都位于服务器内部,因此Spring Boot访问MySQL不需要经过互联网。
这种场景下,3306端口不需要为了Spring Boot访问而允许公网连接。
Spring Boot访问Redis
Spring Boot和Redis都运行在同一台Linux服务器中时,Spring Boot可以连接:
text
127.0.0.1:6379
Spring Boot直接访问服务器本机中的Redis,不需要从公网进入服务器。
这种场景下,6379端口通常不需要允许公网访问。
Spring Boot访问RabbitMQ
Spring Boot和RabbitMQ运行在同一台Linux服务器中时,Spring Boot可以连接:
text
127.0.0.1:5672
RabbitMQ的5672端口只供当前服务器中的应用程序使用时,没有必要允许公网访问。
Nginx访问Spring Boot
假设Nginx和Spring Boot都运行在同一台Linux服务器中,Spring Boot使用8080端口提供Web服务。
Nginx可以通过:
text
127.0.0.1:8080
访问Spring Boot。
如果外部用户只通过Nginx访问Web应用,Spring Boot的8080端口通常也没有必要直接允许公网访问。
SSH隧道访问服务器内部服务
Windows中的Navicat需要管理Linux服务器中的MySQL时,还可以通过SSH隧道访问。
这种方式下,Navicat先建立到Linux服务器的SSH连接,再通过该连接访问服务器内部的MySQL。MySQL本身可以继续只接受本机访问,3306端口不必直接允许公网连接。
因此,不允许3306公网访问并不表示MySQL无法从Windows管理,而是表示不允许Windows直接通过ECS公网IP连接3306端口。
需要开放公网端口的场景
如果客户端程序运行在Linux服务器之外,并且必须直接通过ECS公网IP访问服务器中的某项服务,就需要允许相应端口进行公网访问。
Navicat直接访问MySQL
Navicat运行在Windows电脑中,MySQL运行在阿里云ECS中。
如果Navicat直接使用ECS公网IP和3306端口连接MySQL,则3306端口需要具备公网访问条件。
此时通常需要满足以下条件:
MySQL服务正常运行,MySQL监听允许远程访问的地址,阿里云安全组允许相应的3306入方向访问,Linux防火墙没有阻止连接,并且MySQL存在可用于远程登录的账户。
因此,Windows中的Navicat直接连接远程MySQL,是需要允许3306公网访问的典型场景。
Windows客户端直接访问Redis
Redis Server运行在ECS中,而Redis客户端运行在Windows电脑中。
如果Windows客户端直接通过ECS公网IP连接Redis,则6379端口需要具备公网访问条件。
Redis还应配置相应的身份认证,避免只通过端口开放提供无认证的远程访问。
远程应用直接访问RabbitMQ
RabbitMQ运行在ECS中,而使用RabbitMQ的应用程序运行在另一台计算机中。
如果该应用程序直接通过ECS公网IP连接RabbitMQ,则5672端口需要具备公网访问条件。
浏览器访问RabbitMQ Management
RabbitMQ Management提供Web管理页面,通常使用15672端口。
如果管理人员需要在Windows电脑的浏览器中直接通过ECS公网IP打开RabbitMQ管理页面,则15672端口需要允许相应的公网访问。
如果管理页面只在服务器本机或其他受控方式下使用,则没有必要长期向公网开放15672端口。
Nginx提供公网Web服务
Nginx经常作为Web应用的公网访问入口。
互联网用户使用浏览器访问网站时,需要直接连接Nginx。
HTTP通常使用80端口,HTTPS通常使用443端口。
如果网站使用HTTP,需要允许80端口的相应公网访问;如果网站使用HTTPS,需要允许443端口的相应公网访问。
与MySQL、Redis和RabbitMQ不同,Nginx的80和443端口本身通常就是用于为外部用户提供Web服务的端口。
端口开放场景对比
常见场景可以归纳如下。
| 场景 | 是否需要允许公网访问 |
|---|---|
| Spring Boot和MySQL运行在同一台Linux服务器 | 通常不需要3306 |
| Spring Boot和Redis运行在同一台Linux服务器 | 通常不需要6379 |
| Spring Boot和RabbitMQ运行在同一台Linux服务器 | 通常不需要5672 |
| Nginx和Spring Boot运行在同一台Linux服务器 | 通常不需要8080 |
| Windows通过SSH隧道访问MySQL | 通常不需要3306直接提供公网访问 |
| Windows中的Navicat直接使用ECS公网IP访问MySQL | 需要3306 |
| Windows中的Redis客户端直接使用ECS公网IP访问Redis | 需要6379 |
| 远程应用直接使用ECS公网IP访问RabbitMQ | 需要5672 |
| 浏览器直接使用ECS公网IP访问RabbitMQ Management | 需要15672 |
| Nginx向互联网提供HTTP服务 | 需要80 |
| Nginx向互联网提供HTTPS服务 | 需要443 |
判断原则可以概括为:如果访问服务的程序就在同一台Linux服务器中,通常使用127.0.0.1进行本机访问,不需要为了服务器内部通信允许相应端口从公网访问;如果其他计算机必须直接通过ECS公网IP访问服务器中的某项服务,则需要为该服务使用的端口配置相应的公网访问条件。
阿里云安全组
阿里云安全组用于控制ECS允许通过的网络流量。
Windows电脑访问ECS时,连接从ECS外部进入服务器,因此需要关注安全组中的入方向规则。
假设MySQL已经监听:
text
0.0.0.0:3306
如果安全组没有允许相应的3306端口入方向访问,Windows中的Navicat仍然无法直接通过公网连接MySQL。
如果安全组已经允许3306端口访问,但MySQL仍然只监听:
text
127.0.0.1:3306
外部客户端同样无法使用ECS公网IP连接MySQL。
MySQL监听配置决定MySQL通过哪些本地地址接收连接,安全组决定相应的网络流量是否允许进入ECS。两者控制不同的访问环节。
安全组规则还可以限制允许访问的来源地址。
例如:
text
0.0.0.0/0
表示全部IPv4地址范围。
如果3306端口的入方向规则将来源设置为0.0.0.0/0,表示来自任意IPv4地址的主机都可以尝试访问3306端口。
服务监听配置中的:
text
0.0.0.0
和安全组规则中的:
text
0.0.0.0/0
含义不同。
0.0.0.0表示服务通过当前主机的所有本地IPv4地址接收连接。
0.0.0.0/0表示全部IPv4地址组成的网络范围。
将安全组来源设置为0.0.0.0/0扩大了公网访问范围。MySQL、Redis、RabbitMQ等后端服务在实际部署中通常应根据访问需求限制允许访问的来源地址,并配置相应的身份认证。
网络连通性和身份认证
允许端口公网访问以后,并不表示客户端一定能够正常使用相应服务。
远程访问通常包含网络连接和应用身份认证两个层次。
以Windows中的Navicat连接MySQL为例,可以使用以下命令检查Windows是否能够连接ECS的3306端口:
powershell
Test-NetConnection xxx.xxx.xxx.xxx -Port 3306
如果结果中出现:
text
TcpTestSucceeded : True
表示Windows已经能够建立到目标主机3306端口的TCP连接。
该结果只说明网络连接已经成功,并不表示Navicat已经成功登录MySQL。
Navicat还需要使用正确的MySQL用户名和密码,并且相应账户必须允许该来源进行登录。
Redis和RabbitMQ也存在相同情况。端口能够建立网络连接只是使用服务的基础条件,还需要通过服务本身的认证和权限检查。
典型部署场景
在较简单的单服务器部署中,Nginx、Spring Boot、MySQL、Redis和RabbitMQ可以运行在同一台Linux服务器中。
假设Spring Boot使用8080端口提供Web服务,Nginx作为公网访问入口。
外部用户通过80或443端口访问Nginx。Nginx通过服务器本机的8080端口访问Spring Boot,Spring Boot再通过本机地址访问MySQL、Redis和RabbitMQ。
Spring Boot可以分别使用:
text
127.0.0.1:3306
127.0.0.1:6379
127.0.0.1:5672
访问MySQL、Redis和RabbitMQ。
Nginx可以使用:
text
127.0.0.1:8080
访问Spring Boot。
这种部署方式下,公网用户只需要访问Nginx提供的Web入口。MySQL的3306端口、Redis的6379端口、RabbitMQ的5672端口以及Spring Boot的8080端口都可以限制为服务器内部访问。
如果还需要从Windows直接使用Navicat连接MySQL、使用Redis客户端连接Redis或者使用浏览器打开RabbitMQ Management,则再根据实际访问需求允许对应端口的远程访问。
总结
阿里云ECS属于云服务器实例,Ubuntu是运行在ECS中的操作系统,MySQL Server、Redis Server、RabbitMQ、Nginx和Spring Boot应用等软件可以运行在Ubuntu中。
客户端和服务端程序运行在同一台计算机中时,可以使用127.0.0.1进行本机访问。这种服务器内部通信不经过公网,因此通常不需要允许相应业务端口从公网访问。
客户端运行在服务器之外,并且必须直接使用ECS公网IP访问服务器中的服务时,需要为相应端口配置公网访问条件。例如,Windows中的Navicat直接连接ECS中的MySQL时需要3306端口具备公网访问条件,Redis客户端直接访问Redis时需要6379端口具备公网访问条件,远程应用直接访问RabbitMQ时需要5672端口具备公网访问条件。
Nginx通常作为Web应用的公网入口。外部浏览器访问网站时,需要连接Nginx,因此应根据实际使用的HTTP或HTTPS协议允许80或443端口从公网访问。
服务使用某个端口,并不表示该端口必须允许公网访问。端口是否需要允许公网访问,应根据客户端所在位置和实际访问方式确定。对于只在服务器内部使用的服务,通常采用本机地址访问;对于必须由服务器外部客户端直接通过公网访问的服务,再根据实际需求配置相应的公网访问条件。