架构师实战经验——盘点生产环境知识与工具

盘点知识点及工具

        如下表格列出的是基于多年Java项目实际线上运维总结的知识点,对于java项目生产环境下运用到的最多的几种知识点和工具。本文章并非在说java语言相关的知识,而是盘点那些java项目中经常使用到的非java知识点。

知识点内容
HTTP
  • 报文格式
  • telnet指令
  • curl指令
  • Proxy
Proxy
  • Nginx/Apache
  • 正向代理/反向代理
Load Balance
  • F5
  • 云原生LB
NAT专线
NFS挂载
Certificate证书
Shell常用脚本语言

Shell

        第一个介绍Shell,因为后面很多知识点运用上大多会采用shell脚本来操作。Java开发人对shell多少会接触一些,因为无论是云环境,还是传统的企业网络环境,java服务器多为unix内核服务器,部署、调试、排查问题及日常运维都会使用shell脚本操作。

列出我认为常用的一些shell指令(cd/ls/echo/ps/df/cp/rm/date/top/free/mkdir/rmdir/mv/cp这些基础中基础的指令是常用的,不列出介绍):

  • ping, 常被用来测试服务器是否能够解析或连接目标地址
  • curl, 常用来测试HTTP请求
  • telnet,常用来测试建立tcp连接
  • vi/vim/cat/touch: 常用来查看/编辑文本文件
  • tail/less: 常用来查看/浏览日志文件
  • grep: 关键字查找文件信息
  • openssl:常用来操作SSL、证书相关
  • ifconfig: 操作本机IP相关信息
  • scp: 网络拷贝
  • kill: 删除进程
  • netstat: 操作查看端口
  • pwd: 查看当前目录
  • chmod: 操作文件权限
  • chown: 修改文件拥有者
  • su:切换用户
  • sudo: 以root身份执行指令
  • find: 指定目录搜索文件
  • man: 查看系统文档
  • who/whoami/w: 查看当前会话(用户)状态

HTTP

        HTTP协议最常见的协议,协议内容就不介绍了,这里强调下HTTP的报文格式,平常开发时,我们可以用很多http client工具,如postman/curl命令可以使用,所以不太关注报文,但对于生产环境上,可能没有postman工具/curl指令使用测试http协议,有时需要使用telnet或者openssl s_client指令组装http报文测试、调试。

报文格式

模版

[METHOD] [URL] [VERSION]
[HEADER-NAME]:[HEADER-VALUE]
[HEADERS……]
\n
[REQUEST/RESPONSE BODY]

事例:

  • GET方式:

GET /index.html HTTP/1.1
HOST: localhost

  • POST方式

POST /login HTTP/1.1
HOST:localhost

name=test001&password=123456

请求方式

常用的请求GET/POST/PUT/DELETE,相信大家都很熟悉,除此之外还包括如下几种:

  • HEAD: 获得该次请求的响应头 
  • CONNECT:把请求连接转换到透明的TCP/IP通道,通常用于SSL正向代理建立调用方与被调用的管道式访问。
  • TRACE:激发一个远程的,应用层的请求消息回路。(注:TRACE方法让客户端测试到服务器的网络通路,回路的意思如发送一个请返回一个响应,一般用于Server端的http调试,会获取大量的Server信息,一般生产环境是禁止使用的)
  • OPTIONS: 用于获取当前URL所支持的请求配置。在跨域访问中,如果服务器设置了“Access-Control-Allow-Methods”,“Access-Control-Allow-Headers”,” Access-Control-Allow-Origin”,通过该方法可以获取这些服务器配置。通常跨域访问除了JSONP之外就是这个配置了,当AJAX请求发出去之后浏览器判断是跨域请求,就会先去OPTIONS访问这个接口,获取这些配置信息,验证成功之后再去调用实际的请求,这时会返回请求结果。

还有很冷门的LINK/UNLINK,属于http 1.0协议的请求方式,1.1已经废弃。

所以一般情况下,禁止Server端的TRACE方法是很有必要的,安全性高一点的也会关闭Options,Connect和Head,如果只是web前端Server,则只启用GET/POST。

介绍完常用shell和http报文,接下来看看常用的测试HTTP请求的几种方式。

调试工具

这里介绍的是生产环境中调试使用的技能,并非开发环境上可以使用postman等工具测试,所以得采用shell指令测试。

Telnet

        telnet可以建立tcp通道,除了测试tcp协议联通性之外,还可以做http协议,因HTTP协议基于tcp协议设计出来的。当然对于https协议,telnet就比较麻烦,还得组装ssl报文,telnet平常都用于http://协议,https://协议可以使用openssl s_client。

telnet 127.0.0.1 80
> Connected
----------如下信息手动输入------------
GET / HTTP/1.1
HOST: localhost

----------手动输入结束----------------

HTTP/1.1 521 
Date: Tue, 17 Oct 2023 03:52:20 GMT
Content-Type: text/html
Connection: keep-alive
Cache-Control: no-cache, no-store
Content-length: 1828

<html>...(省略)...</html>

curl

        curl本身就是基于http协议的工具,这里不过多介绍。curl可以做http/https协议,还可以做MAIL,功能强大。

curl http://localhost -v
> Connected
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/1.1 521 
< Date: Tue, 17 Oct 2023 04:02:36 GMT
< Content-Type: text/html
< Connection: keep-alive
< Cache-Control: no-cache, no-store
<
<html>......</html>

openssl s_client

        openssl s_client是用来操作客户端建立服务器端的TCP/SSL协议的指令,对于调试https协议时,可以使用,至少在HTTP协议方面,可以替代telnet做基于tcp协议的HTTP协议。

        openssl s_client支持单向认证和双向认证,双向认证需要提供客户端证书。

单向认证

openssl s_client -connect 127.0.0.1:443 -servername localhost
> Connected
> (SSL握手,服务器信息证书信息等信息省略)
----------如下信息手动输入------------
GET / HTTP/1.1
HOST: localhost

----------手动输入结束----------------

<html>......</html>

双向认证

openssl s_client -connect www.csdn.net:443 -servername www.csdn.net -key ./client.key -cert ./client.cert
> Connected
> (省略服务器返回的证书信息等)
----------如下信息手动输入------------
GET / HTTP/1.1
HOST: localhost

----------手动输入结束----------------

<html>......</html>

        以上servername参数为SSL的SNi信息。当然openssl s_client还有很多参数,如CAfile(服务器端使用了私签证书时,可以设置私签)。

终极杀招

        还有一种情况,就是以上指令都不能用,如K8S环境部署,POD里面没有你这些指令,如何调试?有办法,既然是java程序,那么一定支持java,这个时候就看POD里面是否支持vi/vim等编辑文件的指令,或者支持不支持挂载,我们使用javac/java指令测试。总之就是创建一个java类文件测试http协议。

编写测试java类:

        不依赖任何类,只依赖JDK,这样就可以直接在任何地方编译,十分方便好用。以下代码vi/vim编辑保存为TestOpenConnect.java文件


import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Socket;

public class TestOpenConnect {

    public static void main (String... args) throws MalformedURLException {

       Socket socket = new Socket();
       String host ="localhost";
       int port =80;
       try {
        System.out.println("socket status: "+ socket.isConnected());
        System.out.println("socket connecting" +host+":"+port );
        socket.connect(new InetSocketAddress(host,port ),60);
        System.out.println("socket status: "+socket.isConnected());
        socket.close();
        System.out.println("socket closed");
    } catch (IOException e) {
        e.printStackTrace();
    }
        

    }
    
}

执行如下两个指令:

javac指令编译java类文件,生成jvm能run的class文件,可以用ls指令查看在当前目录下生成的.class文件

java指令执行class文件(不需要加.class),运行main函数。

        按上面的测试代码,意思就是测试localhost的80端口是否可以连接;如果想达到telnet/curl/openssl s_client调试效果,需要编写更多的代码,当然记住原则是不依赖任何的三方jar,只依赖jdk,这样子才方便,不然跟重新写一套项目代码没啥区别,原则就是怎么方便怎么来,十分的好用。

javac TestOpenConnect.java

java TestOpenConnect

Proxy

        这里指的是HTTP协议的代理服务器,如nginx/apache等。一般分为正向代理(Forward Proxy)和反向代理(Reverse Proxy),正向代理又分为管道式代理(tunnel proxy)和路由式代理(route proxy)。

正向代理

        正向代理(Forward Proxy),意思是客户端与目标服务器端中间存在一个中间服务器,客户端为了获取目标服务器内容,客户端需要向中间服务器指定目标服务器并发送请求,然后中间服务器代为请求目标服务器返回内容给到客户端;特点是客户端知道自己的目标服务器地址。

        中间服务器请求目标服务器的方式可为两种管道式和路由式。

注:以下所有测试脚本中,涉及的本机IP地址都是在本机测试用的,实际可以是真实的中间服务器地址和目标服务器地址,并非只有本机才能这么玩。

管道式代理

        管道式基于Http connect实现,中间服务器看不到请求内容;管道式安全级别高,因为HTTP协议要求connect请求方式必须用SSL建立管道,且默认必须是443端口。

建立流程如下:

client到proxy的连接通常是http协议的,不加密,Proxy和Server端的连接是SSL的。

用telnet模拟如下:

  1. 与127.0.0.1:80的中间服务器建立TCP连接
  2. 输入Connect请求方式连接目标服务器localhost:443
  3. 127.0.0.1:80中间服务器代为请求目标服务器localhost:443

注意:建立完成CONNECT连接方式,就可以传输HTTP请求报文,但因为CONNECT请求方式在某些代理服务器上被限制只能请求SSL服务器,所以传输HTTP请求的报文必须得是加密后的报文。理论上如果代理服务器允许CONNECT方式请求HTTP协议的明文,那么这里就可以用明文请求了。如输入"GET http://localhost:8080/ HTTP/1.1 \n HOST: localhost"

telnet 127.0.0.1 80
> Connected
--------------1. 如下手动输入--------
CONNECT localhost:443 HTTP/1.1
Host: localhost
Proxy-Connection: Keep-Alive

--------------手动输入结束--------

-----2. 中间服务器连接上目标服务器-----
> HTTP/1.1 200 Connection established
--------连接上目标服务器结束----------






路由式代理

        路由式基于http Request实现,察看得到请求内容。

建立流程如下:

通常整个流程都是http协议的,不加密。

用telnet模拟下:

  1. 建立与代理服务器的连接
  2. 客户端请求http协议目标服务器完整地址(因为80端口被占用了,另起一个8080端口)
  3. 中间服务器代为请求目标服务器
telnet 127.0.0.1 80
> Connected
--------------如下手动输入--------
GET http://localhost:8080 HTTP/1.1
Host: localhost

--------------手动输入结束--------


小结

  • 当中间服务器处理请求时,如果是HTTPS请求,代理服务器将启用管道式代理,如果是HTTP请求,将启用路由式代理。(多数代理服务器的规则,不能代表所有市场产品)
  • 大多产品在建立管道式代理式,默认只识别目标URL为443端口,如果不是则403。如果要支持其他的端口则需要做额外的配置。
  • 在调试架构过程中,如果遇到正向代理,一定要学会如何使用telnet命令,这样会帮助你快速定位问题
  • 管道式代理和路由式代理报文差异:管道式采用http connect方式,路由式采用转发http报文形式。

反向代理

        反向代理,对于客户端来说,它只知道中间服务器,不知道目标服务器地址,一切取决于中间服务器的代理的配置,如Nginx的location代理配置

Location /web/ {
     proxy_pass http://localhost:8080/
}

流程如下:

telnet模拟如下

  1. 建议与中间服务器的连接
  2. 输入请求中间服务器的报文(telnet的IP端口和输入报文的IP端口是一致的)
  3. 中间服务器读取自己的代理配置文件,识别匹配的上游系统的路由配置,识别之后请求目标服务器。
telnet 127.0.0.1 80
>Connected
-------------------手动输入-----------------
GET http://127.0.0.1/web/index.html HTTP/1.1
HOST : 127.0.0.1

-------------------手动输入结束-------------

TCP/IP代理

以上都在阐述HTTP协议,对于反向代理TCP协议的,如MQ/MQTT等等,可以使用Haproxy或者其他企业级TCP代理;

TCP代理是可以代理HTTP协议的,因为HTTP基于TCP代理实现,但是是4层协议,对于7层协议的路由是做不到的,如通过path/header/cookie等信息路由。

Scoket5代理

Socket5代理其实就是正向代理的一种实现基于tcp的正向代理服务,可以用开源的非开源的产品建立socket5代理,如squid。

总结

  • 反向代理运用广泛,比如API Gateway,软负载,等等
  • 正向代理运用如Mock Server的代理服务器在不改变原有架构下动态指定的代理服务器,代理服务器通过配置是否开启mock,企业内部上网,还有一个比较冷门解决云产品SDK内网运行时指定正向代理服务器代为请求,解决企业内部生产环境Server Farm不能直接连接外网的问题。
  • 软件代理通常使用这两种软件
    • Nginx常用反向代理
    • Apache支持正向代理,反向代理(基本上使用不高,市场基本被nginx占用了)
    • 正向代理服务器也有企业级的Cisco,免费的开源squid

Load Balance

  • 负载均衡,分为硬件和软件两种,硬件F5,软件NGINX/Apache
  • 早期的web工程负载均衡需要解决session共享,有Session复制,Session sticky,Ip Hash。
  • F5,每个LoadBalance机器都有独立的域名和IP。在集群机器中,LoadBalance通过调用KeepAlive地址来确认集群的机器是否有效。
  • 软件Load Balance可以用Nginx/apache/Kong等,对于云厂商也有很多LB产品也可以使用,区别在于是TCP协议还是HTTP协议的Load Balance。

F5

在传统企业网络环境里,F5是必备的load balance,采用Session Sticky机制实现Session共享。

  • F5会隔段时间检测后置Server是否可用,这种机制叫KeepAlive。
  • TCP检测
  • http检测
  • 如果检测失败,则不会请求该Server节点。
  • 这意味着所有申请的系统都要给网络部门提供KeepAlive地址,比如:/KeepAlive.jpg

KeepAlive

  • http检测就是请求http地址是否返回http status 200。
    • curl http://127.0.0.1/KeepAlive.jpg
  • TCP请求其实就是自定义telnet的内容,通常情况下也是http的message
    • telnet 127.0.0.1 80
    • >connected
    • HEAD http://127.0.0.1/KeepAlive.jpg HTTP/1.1
  • 注意F5代理NGINX时,默认会失败。因为NGINX拒绝request message中没有HOST.而F5默认的报文是不提供host的。(这点在某些云产品的LB上也有发现,解决方案雷同)
    • telnet 127.0.0.1 80
    • >connected
    • HEAD http://127.0.0.1/KeepAlive.jpg HTTP/1.1
    • HOST: 127.0.0.1

NAT

NAT(Network Address Translation)是打通两个不同域下的局域网技术,涉及Source,NAT ,Target三个Server元素。一般常见于专线服务。

  • 通常情况下开通NAT,须提供以下四个元素,因为需要开通防火墙设置
    • 源IP及端口(我方Server IP)
    • 目标IP及端口(对方Server IP)
  • 你必须要获得以下信息
    • 如果有NAT 地址,因为做NAT时 ,为了防止双方局域网IP冲突,会做个中转的映射IP叫做NAT ip。
    • 对方IP和端口
  • 调试NAT时,须使用以下命令判断NAT是否打通。
    • telnet
    • ping
    • traceroute
  • 通常防火墙只允许源IP才能访问NAT,而且NAT IP也是有限的,所以通常方案都会在源Server上安装Proxy去实现某些功能。

NFS

NFS(网络文件系统),网络中的机器之间共享文件的技术,一般传统企业网络使用较多。云环境下,更多的是文件挂载mount。

  • 源目录
  • 目标目录
  • 访问权限
  • Owner用户
  • 察看Server NFS情况用df –h命令

Certificate

证书是系统开发中比较重要的环节,关于证书可以观看我之前写的数字证书相关的文章。

数字证书实战经验——基础编-CSDN博客

数字证书实战经验——自建CA中心签发证书-CSDN博客

数字证书实战经验——证书转换(Openssl&Java&Android)-CSDN博客

数字证书实战经验——ASN.1语法及JWKS_车联网服务端架构的博客-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

车联网服务端架构

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值