Aaswk头像
关注

计算机网络核心内容全讲解

文章目录

一、网络分层模型

OSI七层模型 vs TCP/IP四层模型

OSI七层TCP/IP四层核心职责常见协议
应用层应用层为应用程序提供网络服务HTTP、HTTPS、WebSocket、FTP
表示层数据格式转换、加密压缩SSL/TLS
会话层建立、管理、终止会话-
传输层传输层端到端可靠传输TCP、UDP
网络层网络层路由选择、IP寻址IP、ICMP、ARP
数据链路层网络接口层物理寻址、帧封装Ethernet、Wi-Fi
物理层比特流传输网卡、网线

Java开发者重点关注:应用层(HTTP协议)、传输层(TCP/UDP特性)


二、传输层核心:TCP与UDP的抉择

TCP:可靠传输的代价

三次握手(建立连接)
客户端                    服务端
  |                         |
  |------ SYN seq=x ------->|  第一次握手:客户端请求连接
  |                         |
  |<-- SYN+ACK seq=y,ack=x+1|  第二次握手:服务端确认并请求
  |                         |
  |------ ACK ack=y+1 ----->|  第三次握手:客户端确认
  |                         |
 [连接建立,可以传输数据]

为什么需要三次?
防止失效的连接请求突然到达服务端。若客户端第一个SYN因网络延迟很久才到达,两次握手会导致服务端误建立连接并一直等待数据。

四次挥手(断开连接)
客户端                    服务端
  |                         |
  |------ FIN seq=u ------->|  第一次:客户端请求关闭
  |                         |
  |<----- ACK ack=u+1 ------|  第二次:服务端确认
  |                         |  [服务端可能还有数据要发送]
  |<----- FIN seq=w --------|  第三次:服务端请求关闭
  |                         |
  |------ ACK ack=w+1 ----->|  第四次:客户端确认
  |                         |
 [等待2MSL后完全关闭]

TIME_WAIT状态:主动关闭方会等待2MSL(Maximum Segment Lifetime,通常2分钟),确保被动方收到最后的ACK。

TCP核心特性
特性实现机制Java中的体现
可靠传输序列号、确认应答、超时重传Socket数据不会丢失
流量控制滑动窗口接收方告知发送方缓冲区大小
拥塞控制慢启动、拥塞避免、快重传网络拥堵时自动降速
顺序保证序列号排序接收数据顺序与发送一致

UDP:快速但不可靠

特点

  • 无连接(直接发送,无需握手)
  • 不保证可靠性(数据可能丢失、乱序)
  • 无拥塞控制(发送速度不受网络状态影响)
  • 头部开销小(8字节 vs TCP的20字节)

使用场景

  • 实时音视频通话(丢几帧无所谓)
  • DNS查询(数据量小,重试成本低)
  • 游戏状态同步(最新状态覆盖旧状态)

Java中的选择

// TCP - Socket编程
ServerSocket serverSocket = new ServerSocket(8080);
Socket clientSocket = serverSocket.accept();  // 阻塞等待连接

// UDP - DatagramSocket编程
DatagramSocket socket = new DatagramSocket(8080);
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);  // 接收数据报

三、应用层协议:HTTP的演进

HTTP/1.1:经典但有瓶颈

核心特性

  • 持久连接(Keep-Alive):一个TCP连接可发送多个HTTP请求
  • 管道化:可连续发送请求,但响应必须按顺序返回(易造成队头阻塞)

常见问题

// Spring Boot默认配置
server.tomcat.max-connections=10000  // 最大连接数
server.tomcat.max-threads=200        // 最大工作线程
server.connection-timeout=20000      // 连接超时20秒

HTTP/2:多路复用的革命

核心改进

  1. 二进制分帧:将消息拆分为帧,一个TCP连接可交错传输多个请求/响应
  2. 头部压缩:HPACK算法压缩Header,减少冗余
  3. 服务器推送:服务端主动推送资源(如CSS、JS)
HTTP/1.1: 请求1 -> 响应1 -> 请求2 -> 响应2(串行)
HTTP/2:   请求1、请求2并发 -> 响应1、响应2交错返回(并行)

Java中的支持

// Spring Boot 2.x+,嵌入式Tomcat 9+原生支持HTTP/2
server.http2.enabled=true
server.ssl.enabled=true  // HTTP/2需要TLS

HTTP/3:基于QUIC的未来

核心变化

  • 传输层从TCP改为QUIC(基于UDP)
  • 解决TCP的队头阻塞问题
  • 连接迁移(切换Wi-Fi/4G不断线)

四、HTTP核心知识点

请求方法与幂等性

方法语义幂等性安全性使用场景
GET获取资源查询数据
POST创建资源提交表单、上传文件
PUT完整更新更新整个用户信息
PATCH部分更新只更新用户昵称
DELETE删除资源删除订单
OPTIONS查询支持的方法CORS预检请求

幂等性:多次执行产生的效果与一次执行相同
示例DELETE /user/123 删除一次是删除,删除十次结果仍是该用户被删除

常见状态码

2xx 成功
  • 200 OK:请求成功
  • 201 Created:资源创建成功(POST后返回)
  • 204 No Content:成功但无返回内容(DELETE后常用)
3xx 重定向
  • 301 Moved Permanently:永久重定向(搜索引擎会更新索引)
  • 302 Found:临时重定向
  • 304 Not Modified:资源未修改,使用缓存
4xx 客户端错误
  • 400 Bad Request:请求参数错误
  • 401 Unauthorized:未认证(没登录)
  • 403 Forbidden:已认证但无权限
  • 404 Not Found:资源不存在
  • 429 Too Many Requests:请求过于频繁(限流)
5xx 服务端错误
  • 500 Internal Server Error:服务器内部错误
  • 502 Bad Gateway:网关错误(Nginx无法连接后端)
  • 503 Service Unavailable:服务暂时不可用(过载或维护)
  • 504 Gateway Timeout:网关超时

RESTful API设计原则

// ❌ 不好的设计
GET  /getUserById?id=123
POST /updateUser
POST /deleteUser

// ✅ RESTful风格
GET    /users/123           // 获取用户
POST   /users               // 创建用户
PUT    /users/123           // 完整更新用户
PATCH  /users/123           // 部分更新用户
DELETE /users/123           // 删除用户
GET    /users/123/orders    // 获取用户的订单列表

核心原则

  1. 使用名词而非动词(资源导向)
  2. 利用HTTP方法表达操作
  3. 使用层级结构表达关系
  4. 返回合适的状态码

五、HTTPS:安全传输

HTTP vs HTTPS

HTTP:  客户端 <--明文传输--> 服务端(可被窃听、篡改)
HTTPS: 客户端 <--加密传输--> 服务端(通过SSL/TLS加密)

HTTPS工作流程

  1. 客户端发起请求Client Hello(支持的加密套件、随机数)
  2. 服务端返回证书Server Hello(选定加密套件、数字证书、随机数)
  3. 客户端验证证书:检查证书是否由可信CA签发、是否过期、域名是否匹配
  4. 协商密钥
    • 客户端生成预主密钥(Pre-Master Secret)
    • 用服务端公钥加密后发送
    • 双方各自计算出会话密钥(对称加密密钥)
  5. 加密通信:使用会话密钥进行对称加密传输

为什么要结合对称和非对称加密?

  • 非对称加密安全但慢(用于密钥交换)
  • 对称加密快但密钥分发困难(用于数据传输)

Java中配置HTTPS

// Spring Boot application.yml
server:
  port: 8443
  ssl:
    key-store: classpath:keystore.p12
    key-store-password: yourpassword
    key-store-type: PKCS12
    key-alias: tomcat

生成自签名证书(测试用):

keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 \
  -storetype PKCS12 -keystore keystore.p12 -validity 3650

六、网络安全:常见攻击与防护

XSS(跨站脚本攻击)

攻击原理:将恶意JavaScript注入网页

<!-- 用户输入:<script>alert('XSS')</script> -->
<div>评论内容:<script>alert('XSS')</script></div>

防护措施

// 1. 转义HTML特殊字符
import org.apache.commons.text.StringEscapeUtils;
String safe = StringEscapeUtils.escapeHtml4(userInput);

// 2. 使用模板引擎自动转义(Thymeleaf)
<div th:text="${comment}"></div>  <!-- 自动转义 -->

// 3. 设置CSP响应头
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'

CSRF(跨站请求伪造)

攻击原理:诱导用户在已登录状态下访问恶意网站,利用Cookie自动发送请求

<!-- 恶意网站的页面 -->
<img src="http://bank.com/transfer?to=hacker&amount=10000">
<!-- 用户浏览器会自动带上bank.com的Cookie -->

防护措施

// Spring Security自动启用CSRF保护
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
}

// 前端需要在请求中携带CSRF Token
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

SQL注入

攻击原理:在输入中插入SQL代码

// ❌ 危险的拼接SQL
String sql = "SELECT * FROM users WHERE username = '" + username + "'";
// 输入:admin' OR '1'='1
// 实际执行:SELECT * FROM users WHERE username = 'admin' OR '1'='1'(返回所有用户)

// ✅ 使用预编译语句
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);  // 自动转义特殊字符

七、跨域问题与CORS

同源策略

浏览器安全机制:协议、域名、端口完全相同才是同源

http://example.com:80/api  与以下地址的关系:
✅ http://example.com:80/user      (同源)
❌ https://example.com:80/api      (协议不同)
❌ http://api.example.com:80/api   (域名不同)
❌ http://example.com:8080/api     (端口不同)

CORS(跨域资源共享)

简单请求

满足以下条件的请求:

  • 方法:GET、POST、HEAD
  • 头部仅限:Accept、Accept-Language、Content-Language、Content-Type(仅application/x-www-form-urlencodedmultipart/form-datatext/plain

浏览器直接发送请求,携带Origin头:

GET /api/users HTTP/1.1
Origin: http://example.com

服务端响应:

Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Credentials: true
预检请求(Preflight)

非简单请求(如PUT、DELETE或自定义Header)需要先发送OPTIONS请求:

OPTIONS /api/users HTTP/1.1
Origin: http://example.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: Authorization

服务端响应:

Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization
Access-Control-Max-Age: 86400  // 预检结果缓存1天

Spring Boot配置CORS

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://localhost:3000")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

// 或使用注解
@RestController
@CrossOrigin(origins = "http://localhost:3000")
public class UserController { }

八、DNS解析过程

用户访问www.example.com的完整流程:

1. 浏览器缓存  →  2. 操作系统缓存  →  3. 本地DNS服务器(ISP)
                                         ↓(未命中)
                                    4. 根DNS服务器(返回.com的地址)
                                         ↓
                                    5. 顶级域DNS服务器(返回example.com的地址)
                                         ↓
                                    6. 权威DNS服务器(返回www.example.com的IP)
                                         ↓
                                    缓存并返回IP地址给浏览器

递归查询 vs 迭代查询

  • 递归:客户端只问一次,DNS服务器负责查到底
  • 迭代:DNS服务器返回下一步应该问谁,客户端继续问

Java中查询DNS

InetAddress address = InetAddress.getByName("www.example.com");
System.out.println(address.getHostAddress());  // 输出IP地址

九、连接池:提升性能的关键

为什么需要连接池?

创建TCP连接的成本:

  1. 三次握手(至少1.5个RTT)
  2. TLS握手(HTTPS需要额外2个RTT)
  3. 系统资源分配(文件描述符、内存)

示例对比

// ❌ 每次请求创建新连接
for (int i = 0; i < 100; i++) {
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.connect();  // 每次都三次握手
    // ...
    conn.disconnect();  // 每次都四次挥手
}

// ✅ 使用连接池复用连接
CloseableHttpClient client = HttpClients.custom()
    .setMaxConnTotal(200)  // 最大连接数
    .setMaxConnPerRoute(20)  // 每个路由最大连接数
    .build();

for (int i = 0; i < 100; i++) {
    client.execute(request);  // 复用已有连接
}

数据库连接池配置

// HikariCP(Spring Boot默认)
spring.datasource.hikari.maximum-pool-size=20     // 最大连接数
spring.datasource.hikari.minimum-idle=5           // 最小空闲连接
spring.datasource.hikari.connection-timeout=30000 // 获取连接超时30秒
spring.datasource.hikari.idle-timeout=600000      // 空闲连接存活10分钟
spring.datasource.hikari.max-lifetime=1800000     // 连接最长生命周期30分钟

调优建议

  • maximum-pool-size ≈ (CPU核心数 × 2) + 磁盘数
  • 避免设置过大(上下文切换开销、数据库压力)
  • 监控连接使用率,按需调整

十、超时配置:避免无限等待

三种超时类型

// 1. 连接超时(Connection Timeout)
//    从发起连接到TCP三次握手完成的时间
RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory factory = 
    new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(5000);  // 5秒内必须建立连接
restTemplate.setRequestFactory(factory);

// 2. 读取超时(Read Timeout)
//    从发送请求到读取完响应的时间
factory.setReadTimeout(10000);  // 10秒内必须读取完响应

// 3. 套接字超时(Socket Timeout)
//    两个数据包之间的最大间隔时间
RequestConfig config = RequestConfig.custom()
    .setSocketTimeout(10000)  // 10秒内必须收到下一个数据包
    .build();

Spring Boot全局配置

spring:
  mvc:
    async:
      request-timeout: 30000  # Controller异步请求超时
  datasource:
    hikari:
      connection-timeout: 30000  # 获取数据库连接超时
  redis:
    timeout: 2000  # Redis操作超时

十一、网络IO模型

BIO(Blocking I/O)- 阻塞IO

ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
    Socket socket = serverSocket.accept();  // 阻塞等待连接
    // 每个连接需要一个线程处理
    new Thread(() -> {
        InputStream in = socket.getInputStream();
        in.read(buffer);  // 阻塞等待数据
    }).start();
}

问题:高并发下需要大量线程(C10K问题)

NIO(Non-blocking I/O)- 非阻塞IO

Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);  // 设置非阻塞
serverChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
    selector.select();  // 阻塞等待事件
    Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
    while (keys.hasNext()) {
        SelectionKey key = keys.next();
        if (key.isAcceptable()) {
            // 处理新连接
        } else if (key.isReadable()) {
            // 处理读事件
        }
        keys.remove();
    }
}

优势:一个线程通过Selector管理多个连接

AIO(Asynchronous I/O)- 异步IO

AsynchronousServerSocketChannel server = 
    AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080));

server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
    @Override
    public void completed(AsynchronousSocketChannel channel, Void attachment) {
        server.accept(null, this);  // 继续接受下一个连接
        // 异步读取数据
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        channel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                // 读取完成的回调
            }
            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                // 失败的回调
            }
        });
    }
    @Override
    public void failed(Throwable exc, Void attachment) { }
});

Netty框架

高性能NIO框架,解决原生NIO复杂性:

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();

ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
 .channel(NioServerSocketChannel.class)
 .childHandler(new ChannelInitializer<SocketChannel>() {
     @Override
     protected void initChannel(SocketChannel ch) {
         ch.pipeline().addLast(new StringDecoder());
         ch.pipeline().addLast(new StringEncoder());
         ch.pipeline().addLast(new MyBusinessHandler());
     }
 });

ChannelFuture f = b.bind(8080).sync();

应用场景

  • RPC框架(Dubbo底层)
  • 消息队列(RocketMQ、Kafka客户端)
  • 游戏服务器
  • IM即时通讯

十二、负载均衡与反向代理

负载均衡算法

1. 轮询(Round Robin)
upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

每个请求依次分配给下一台服务器。

2. 加权轮询(Weighted Round Robin)
upstream backend {
    server 192.168.1.10:8080 weight=3;  # 性能强,分配更多请求
    server 192.168.1.11:8080 weight=2;
    server 192.168.1.12:8080 weight=1;
}
3. IP哈希(IP Hash)
upstream backend {
    ip_hash;  # 同一客户端IP始终路由到同一服务器
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

优点:会话保持(用户登录状态不会丢失)
缺点:服务器宕机后,部分用户需要重新登录

4. 一致性哈希(Consistent Hash)

解决IP Hash在服务器增减时大量请求重新映射的问题。

5. 最少连接(Least Connections)
upstream backend {
    least_conn;  # 将请求分配给连接数最少的服务器
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

Nginx反向代理配置

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # 超时配置
        proxy_connect_timeout 5s;
        proxy_read_timeout 30s;
        
        # 失败重试
        proxy_next_upstream error timeout http_500;
    }
}

Java应用获取真实IP

@RequestMapping("/ip")
public String getClientIP(HttpServletRequest request) {
    String ip = request.getHeader("X-Real-IP");
    if (ip == null || ip.isEmpty()) {
        ip = request.getHeader("X-Forwarded-For");
    }
    if (ip == null || ip.isEmpty()) {
        ip = request.getRemoteAddr();
    }
    return ip;
}

十三、常用排查工具

1. ping - 测试连通性

ping example.com
# 输出:
# 64 bytes from 93.184.216.34: icmp_seq=1 ttl=56 time=12.3 ms

# -c 指定次数
ping -c 4 example.com

原理:发送ICMP Echo Request,等待Echo Reply

2. telnet - 测试端口连通性

telnet example.com 80
# 成功:Connected to example.com
# 失败:Connection refused(端口未开放)或 Connection timed out(防火墙拦截)

3. curl - 测试HTTP请求

# 基本请求
curl https://api.example.com/users

# 显示响应头
curl -i https://api.example.com/users

# POST请求
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"张三","age":25}'

# 显示详细过程(包含DNS解析、TCP握手)
curl -v https://api.example.com/users

# 测试响应时间
curl -o /dev/null -s -w "时间:%{time_total}秒\n" https://example.com

4. netstat - 查看网络连接

# 查看所有TCP连接
netstat -an | grep ESTABLISHED

# 查看端口占用
netstat -tuln | grep 8080

# 统计各状态连接数
netstat -an | awk '/tcp/ {print $6}' | sort | uniq -c

常见状态

  • LISTEN:服务器正在监听端口
  • ESTABLISHED:连接已建立
  • TIME_WAIT:主动关闭方等待2MSL
  • CLOSE_WAIT:被动关闭方等待应用关闭连接(过多说明代码未正确关闭连接)

5. tcpdump/Wireshark - 抓包分析

# 抓取8080端口的数据包
tcpdump -i any port 8080 -w capture.pcap

# 抓取特定主机的HTTP流量
tcpdump -i eth0 host 192.168.1.100 and port 80

# 查看TCP握手过程
tcpdump -i any port 8080 -nn -S 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0'

用Wireshark打开capture.pcap文件,可视化分析TCP流、重传、延迟等。

6. nslookup/dig - DNS查询

# 查询域名对应的IP
nslookup example.com

# 查询指定DNS服务器
nslookup example.com 8.8.8.8

# dig更详细的输出
dig example.com

# 查询特定记录类型
dig example.com MX  # 邮件服务器记录
dig example.com TXT # TXT记录(SPF、DKIM等)

十四、实战场景与问题排查

场景1:接口响应慢

排查步骤

  1. 确认是否网络问题
curl -o /dev/null -s -w "DNS解析:%{time_namelookup}s\nTCP连接:%{time_connect}s\nTLS握手:%{time_appconnect}s\n响应时间:%{time_starttransfer}s\n总时间:%{time_total}s\n" \
  https://api.example.com/slow-endpoint
  1. 检查数据库慢查询
-- MySQL慢查询日志
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
  1. 查看应用日志
@Slf4j
@Aspect
@Component
public class PerformanceAspect {
    @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long duration = System.currentTimeMillis() - start;
        if (duration > 1000) {
            log.warn("慢接口:{} 耗时:{}ms", joinPoint.getSignature(), duration);
        }
        return proceed;
    }
}

场景2:大量CLOSE_WAIT连接

原因:代码未正确关闭连接

// ❌ 错误示例:未关闭连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream in = conn.getInputStream();
// 忘记关闭 in 和 conn

// ✅ 正确示例:使用try-with-resources
try (CloseableHttpClient client = HttpClients.createDefault();
     CloseableHttpResponse response = client.execute(request)) {
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);  // 确保连接释放
}

场景3:跨域请求失败

排查步骤

  1. 查看浏览器控制台错误
Access to XMLHttpRequest at 'https://api.example.com/users' from origin 
'http://localhost:3000' has been blocked by CORS policy
  1. 检查预检请求
curl -X OPTIONS https://api.example.com/users \
  -H "Origin: http://localhost:3000" \
  -H "Access-Control-Request-Method: DELETE" \
  -i
  1. 确认服务端配置
// 确保CORS配置覆盖了实际的请求源
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")

场景4:HTTPS证书错误

常见错误

  • ERR_CERT_AUTHORITY_INVALID:证书未由可信CA签发(自签名证书)
  • ERR_CERT_COMMON_NAME_INVALID:证书域名与访问域名不匹配
  • ERR_CERT_DATE_INVALID:证书已过期或尚未生效

Java忽略证书验证(仅测试环境)

TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() { return null; }
        public void checkClientTrusted(X509Certificate[] certs, String authType) { }
        public void checkServerTrusted(X509Certificate[] certs, String authType) { }
    }
};

SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

十五、性能优化建议

1. 启用HTTP/2

// Spring Boot配置
server.http2.enabled=true

收益:多路复用减少连接数,头部压缩减少带宽

2. 使用连接池

// RestTemplate使用连接池
@Bean
public RestTemplate restTemplate() {
    PoolingHttpClientConnectionManager cm = 
        new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(200);
    cm.setDefaultMaxPerRoute(20);
    
    HttpClient httpClient = HttpClients.custom()
        .setConnectionManager(cm)
        .build();
    
    return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
}

3. 启用Gzip压缩

# Spring Boot配置
server:
  compression:
    enabled: true
    mime-types: text/html,text/xml,text/plain,text/css,application/json
    min-response-size: 1024  # 大于1KB才压缩

4. 合理设置超时

spring:
  mvc:
    async:
      request-timeout: 30000  # 30秒
  datasource:
    hikari:
      connection-timeout: 5000  # 5秒

5. 使用CDN加速静态资源

<!-- 使用CDN加载jQuery -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>

6. 启用HTTP缓存

@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    User user = userService.findById(id);
    return ResponseEntity.ok()
        .cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES))  // 缓存10分钟
        .eTag(String.valueOf(user.getVersion()))  // ETag用于验证缓存
        .body(user);
}

十六、知识点清单

理论基础

  • OSI七层模型与TCP/IP四层模型
  • TCP三次握手/四次挥手、TIME_WAIT状态
  • TCP vs UDP的适用场景

HTTP协议

  • HTTP/1.1、HTTP/2、HTTP/3的演进
  • 常见状态码的含义(200、301、400、401、403、404、500、502、504)
  • RESTful API设计原则
  • 请求方法与幂等性

安全相关

  • HTTPS工作原理(对称加密+非对称加密)
  • XSS、CSRF、SQL注入的防护
  • CORS跨域问题的解决
  • 数字证书与CA认证

性能优化

  • 连接池的作用与配置(数据库、HTTP)
  • 超时设置(连接超时、读取超时、套接字超时)
  • HTTP缓存策略(ETag、Cache-Control)
  • Gzip压缩与HTTP/2优化

实战能力

  • 使用curl、telnet、netstat排查网络问题
  • 负载均衡算法的选择(轮询、加权、IP哈希、最少连接)
  • Nginx反向代理配置
  • 获取客户端真实IP(X-Forwarded-For)

进阶知识

  • NIO/AIO/Netty框架
  • DNS解析过程(递归与迭代查询)
  • WebSocket实时通信
  • 网络IO模型对比(BIO、NIO、AIO)

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/weixin_45467593/article/details/164428404

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--