Netfilter和iptables命令详解,从入门到精通

news2024/11/16 19:28:53

本文目录

  • 1、netfilter架构和工作原则简介
  • 2、iptables操作命令说明
    • 2.1 、Filtering Specifications
    • 2.2、Target Specifications
    • 2.3、一个基于Linux的基本的防火墙的配置例子

netfilter 是Linux内核里网络部分的一个重要框架,内核通过netfilter完成IP报文的一些操作。iptables是netfilter的前端命令行工具,Linux系统管理员可以通过iptables工具告诉netfilter如何处理接收到的,转发的和准备发送出去的IP报文。netfilter通常以五表四链+链里的规则提供IP报文处理的功能,其中最重要的二个功能是报文过滤和地址转换(NAT)。netfilter工作在Linux的TCP/IP协议栈,本质上,netfilter是在Linux的TCP/IP协议栈的各层各个处理点插入的一套回调函数,以让用户可以在指定点对IP报文进行处理。

1、netfilter架构和工作原则简介

  1. Netfilter的工作过程:
  • 用户通过iptables告诉netfilter如何处理进出Linux的报文。
  • netfilter分析所有IP报文的IP头
  • 如果有命中中的规则,则按照规则指定的方法处理该报文
  1. 看起来很简单,但实际处理过程的实现是比较复杂的。netfilter包含一系列的tables,每个table里包含一些默认的规则集合称为chain, 每个chain里包含一个或者多个rules, 所以netfilter是由tables-chains-rules三层结构构成的。这就是我们通常所说的五表四链。默认的table是filter table,它包含了以下3个chains:
  • INPUT: 对目标地址为Linux本身的IP地址的IP地方进行处理的规则放在这这个chain里。
  • FORWARD: 对目标地址为其它主机的IP地址,Linux主机需要转发的IP报文的处理的规则放在这这个chain里。
  • OUTPUT: 对本Linux产生的,要发送给其它主机的IP报文的处理的规则放在这这个chain里。

还有常用的nat tables, mangle tables,这些表格所包含的chains可以参见:netfilter的各个tables简介

  1. 总体来说,IP报文在netfilter里的处理过程如下图所示
  • 先由各个tables里的prerouting chain处理,然后送给input/forward chain处理,发送时先后经过output和postrouting chain处理。

图1

  • 具体的处理路径见下图的标颜色的部分,根据报文是进链路成还是直接进IP层进行处理,不一样分成链中层处理和IP层处理的不同路径。
    在这里插入图片描述
  • 不考虑raw table的情况下的IP层处理流程如下图:
    在这里插入图片描述
    第一步:报文到达TCP/IP协议栈后, 由bridge check检查,决定这个报文转到IP层处理后先由mangle table的PREROUTING chain里的规则进行分析。 这里可以对IP报文进行所有mangle table可以支持的操作(比如:TOS字节的修改,标记报文等) 。
    第二步:报文转到nat table的pre-routing chain 进行分析处理,此外可以做SNAT, DNAT,端口重映射等等。因为DNAT(destination network address translation)修改了接收到的报文的目标地址,所以逻辑上决定着必须在报文进入内核的路由转发决定处理模块前完成,这样路由转发处理模块才可以按照修改后的目标IP地址,将报文按照修改后的目标地址将报文转发到正确的目标主机。
    第三步:内核的路由转发模块,决定后续如何转发报文(转发或者说这个报文是发送给本机的)。这不是netfilter的功能。
    第四步:如果这个IP报文是发送给本机的,报文会进入mangle table的INPUT chain (修改TOS,打标记等)进行处理。然后进入filter table的INPUT chain进行处理(可以accepted, rejected 或者dropped等)。 如果报文被接收,那么就送上层应用程序处理(比如说一个WEB请求),上层应用产生一个响应报文(比如web浏览的响应)报文,这个报文会被送到mangle table的OUPUT chain 然后是nat table 的OUTPUT chain 再是filter table的OUTPUT chain进行处理(这里处理完成后,还有一个recheck route重新路由的过程,见文章开始的二个图)。最后送到mangle table的 POSTROUTING chain 和nat table 的POSTROUTING chain处理后,最后到达网卡进行发送。

这里描述的是报文如何在预置的table的预置chain中的处理流程。在实际网络中,用户可以定制用户自己的chain,然后通过预置chain将报文转到客户定制的用户chain中进行处理。比如:我们可以为SSH登录连接创建命名为SSH-chain的用户自定义chain然后在INPUT chain中告诉内核把接收到的目标端口为22的TCP报文送到SSH-chain进行处理。

2、iptables操作命令说明

iptables对chain的操作支持以下操作命令:

  • 列出指定chain里的规则rules (iptables –L CHAIN).
  • 修改指定chain的处理动作policy(iptables –P CHAIN ACCEPT).
  • 创建一个用户自定义的chain (iptables –N CHAIN).
  • 删除指定chain里的所有规则rules (iptables –F CHAIN).
  • 删除指定的chain (iptables –D CHAIN),只在chain已经为空的情况下可以操作
  • 清空指定chain的计数器 (iptables –Z CHAIN). chain里的每条规则都有一个计数器来统计命中规则的报文的数量,本命令用于重置计数器。

对于上述的–L, –F, –D, –Z 这几个操作,如果没有指定chain的名字,那么默认对table里的所有chain生效,如果没有指定table则默认为filter table。
如果你想要指定table则需要用-t来指定:iptables –t nat …

iptables对规则的操作支持以下操作命令:

  • 向指定chain里添加一条rule,放在最下方------(iptables –A)
  • 向指定chain里插入一条rule,放在最上方------(iptables –I)
  • 替换指定chain里已有的一条rule------------------(iptables –R)
  • 删除指定chain里的指定rule------------------------(iptables –D)

iptables –A 向指定chain里添加一条rule,添加的这条rule是放在rule list的最后一条;iptables –I 向指定chain里插入一条rule,做为规则列表里的第一条规则。当然,你也可以向rule list的指定位置插入一条规则,如iptables –I CHAIN 4 可以在rule list的第4个位置插入一条新的规则。

iptables –D 可以通过指定规则,也可以通过指定规则的位置这二种方式删除指定规则。
添加一条规则的命令格式如下:

iptables –A <CHAIN_NAME><filtering specifications>… -j <TARGET>

以Filtering specifications字段指定的规则去分析IP报文,命中的报文则用TARGET字段指定的动作去进行操作。

2.1 、Filtering Specifications

iptables的规则支持通过指定网卡,指定协议,指定端口等等过滤条件分析识别IP报文,这些过滤条件还可以被联合起来使用,这给过滤规则提供了最好的灵活性和广泛性。

  1. Filtering specifications for Layer2:

-i 和 -o 用于指定网络接口设备,-i是"–in-interface"的缩写,表示接收数据包的网卡,-o是"–out-interface"的缩写,表示发送数据包的网卡。
+是一个通配符,比如-i eth+ 表示所以以eth三个字母开关的网卡设备,使用通配符可以让我们一次性把规则配置给多个网卡.

"!"表示非或者说取反,比如-i ! eth1 表示eth1收到的报文不会用指定规则去分析与命中。

注意OUTPUT和POSTROUTING chains没有输入网络设备接口,所以这二个chains中的规则不能使用 -i 选项。同样INPUT和PREROUTING chains 没有输出网络设备接口,所以这二个chains中的规则不能使用 -o 选项。
  1. Filtering specifications for Layer3:

在IP层,支持以源IP地址(-s, --src, or --source), 以目标IP地址(-d,–dst, or --destination) 。注意这里的源IP地址和目标IP地址,可以是主机IP地址,IP子网或者域名(如 “-s 217.207.125.58”, “-s www.packtpub.com”, or “-s 217.207.125.58/32”).
使用域名来过滤时,如果对于多IP地址的域名而言,使用域名来过滤的效果等同时将添加规则时DNS服务器为这个域名解析出来的所有IP都加入到规则中。

  1. Filtering specifications for Layer4:
    在传输层,-p参数是"–protocol"的缩写,可以用协议名tcp, udp, or icmp来指定协议类型。
  • 如果是ICMP,还可以用"–icmp-type"来进一步指定ICMP报文的类型。

  • 如果是UDP,可以用"–source-port" or “–sport” and “–destination-port” and "–dport"来进一步指定源和目标端口号。

  • 如果是TCP,TCP, 除上上述的源和目标端口外,还可以用"–tcp-flags", “–syn” and “–tcp-option"选项,其中TCP flags可以使用"SYN ACK FIN RST URG PSH ALL NONE”; --syn"用于识别发起TCP连接的报文,等价于:“–tcp-flags SYN,RST,ACK SYN”。“–tcp-option” 用于过滤指定的tcp option字段的值的报文。

      注意L2, L3, L4既链路层,IP层和传输层的Filtering specifications可以在同一条规则里联合使用。
    

netfilter/iptables还有一个专门的项目来开发实现额外的分析规则rules,这个项目被称为"patch-o-matic", 可以在这个项目的官方网站 http://www.netfilter.org/projects/patch-o-matic/index.html 看到详细介绍。

iptables/netfilter还计划了将rules过滤规则拓展到支持OSI 7层模型里的所有层级的项目,叫l7-filter后面有机会我们可以起一个文章来专门讲讲这个l7-filter的功能。

2.2、Target Specifications

在filter table里,最常用的Target目标的动作为DROP和ACCEPT。如果有一个报文命中了上一章中描述的某条rule规则,然后这条规则的目标的动作是DROP,那么内核会简单的丢弃这个报文,然后就不会去匹配其它规则了。如果目标动作是ACCEPT,那么同样这个包就会被接收下来,而不再继续去匹配其它当前table里的当前chain里的其它规则。还有一个目标动作为REJECT,如果目标动作是REJECT的话,内核会丢弃该报文,并发送一人ICMP报文到被丢弃报文的源IP地址,告之发送方这是一个ICMP 'port unreachable’错误,如果你要自定义ICMP错误信息的话,需要用"–reject-with"选项来替代REJECT。
当然,除了上述DROP, REJECT, ACCEPT, REJECT-WITH之外,目标的动作target也可以是转发指定报文到用户自定义的chain去进行进一步处理。如:我们已经用

iptables -N SSH

创建了一个叫SSH的用户自定义的chain,那么我们就可以用以下命令,将所有目标端口为22的TCP报文转发到SSH chain进行进一步处理。

iptables -A INPUT -p tcp --dport 22 -j SSH

还有一个很有用的目标动作target叫LOG,当报文命中某个规则时,就会在内核log里(dmesg 或者syslogd)记录这个报文, LOG target 提供多个可配置的子项:

  • –log-level level: 定义log的级别为 debug, info, notice, warning, err, crit, alert, and emerg(对应数字为7-0)
  • –log-prefix prefix: 提供最大29字节的log前缀字符串,
  • –log-tcp-sequence: Logs TCP的序列号
  • –log-tcp-options: Logs TCP的option字段的值
  • –log-ip-options: Logs IP的option字段的值
  • –log-uid: Logs产生该报文的用户进程的进程号
    目标动作target为LOG的规则,有一点和上面的ACCEPT, DROP, REJECT不太一样,报文命中这个LOG为target的rule后,会继续去匹配同一个table的同一个chain里的其它规则。注意为了防止log泛洪功击,我们只应该对有限的报文进行LOG的目标动作。

以下是一个以用户自定义chain SSH的例子的使用用例:

  1. 之前我们已经用如下二个命令创建了SSH chain, 并将收到的目标端口为22的TCP报文转发给SSH chain处理
iptables -N SSH
iptables -A INPUT -p tcp --dport 22 -j SSH
  1. 现在我们只接收ACCEPT从以下二个网段过来的SSH请求:192.168.0.0/27 and 10.10.15.0/24,记录LOG其它地址发过来的SSH请求,并限制LOG数量为5次每秒,以防止泛洪LOG攻击。所以我们在SSH chain里增加如下二条规则:
iptables -A SSH -s 192.168.0.0/27 -j ACCEPT
iptables -A SSH -s 10.10.15.0/24 -j ACCEPT
  1. 添加记录其它SSH请求的LOG目标动作,然后丢弃不可信主机发来的SSH请求
iptables -A SSH -m limit --limit 5/s -j LOG
iptables -A SSH -j DROP
  1. 以下是验证配置是否成功:
sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
SSH        tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain SSH (1 references)
target     prot opt source               destination         
LOG        all  --  0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4
ACCEPT     all  --  192.168.3.0/24       0.0.0.0/0           
ACCEPT     all  --  10.0.0.0/24          0.0.0.0/0           
DROP       all  --  0.0.0.0/0            0.0.0.0/0 
  1. 然后可以用-v选项来查看命中次数:
sudo iptables -L -n -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  760 53836 SSH        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain SSH (1 references)
 pkts bytes target     prot opt in     out     source               destination         
  376 22344 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4
  659 45536 ACCEPT     all  --  *      *       192.168.3.0/24       0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       10.0.0.0/24          0.0.0.0/0           
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0   
  1. 然后使用dmesg命令可以看到如下log记录,说明我们从192.168.3.88收到一个SSH连接。
[26915.359507] IN=eth0 OUT= MAC=00:e0:99:62:ec:b6:70:b5:e8:4b:95:a9:08:00 SRC=192.168.3.88 DST=192.168.3.66 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=10784 DF PROTO=TCP SPT=41118 DPT=22 WINDOW=501 RES=0x00 ACK URGP=0 

后续我们还会描述nat table和mangle table的targets目标动作的使用,注意本文只描述了最常用 的target, 如果你需要更多的target详细可以自行查询patch-o-matic项目。

2.3、一个基于Linux的基本的防火墙的配置例子

以下我们为Linux系统创建一个最基本的防火墙规则。默认的情况下Linux的默认target目标动作是在所有table的所有chain上都是ACCEPT。

#!/bin/bash
#assign variable $IPT with the iptables command
IPT=/sbin/iptables
#set policies on each chain
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT #default, but set it anyway
#flush all rules in the filter table
$IPT -F
#allow traffic on the loopback interface
$IPT -A INPUT -i lo -j ACCEPT
#allow icmp traffic
$IPT -A INPUT -p icmp -j ACCEPT
#allow incoming DNS traffic
$IPT -A INPUT -p udp --sport 53 -j ACCEPT
#allow established TCP connections
$IPT -A INPUT -p tcp ! --syn -j ACCEPT
  1. 把INPUT和FORWARD chains的总体策略设置成DROP
  2. 把OUTPUT chain设置成ACCEPT
  3. 本主机不打开转发功能,所以FORWARD chain里不添加任何规则。
  4. 不往OUTPUT chain里添加任何规则,因为我们默认我们可以发送任何报文出去
  5. 把filter table里的所有规则都删除
  6. 有些程序在主机内通信也借用了TCP/IP那么它是走lo口的,我们认为lo口上的报文全部是安全的,所以在INPUT chain里把lo口的目标动作target设置成ACCEPT
  7. 允许接收ICMP报文,使本机在网络上可以被其它主机ping通,也说traceroute, mtr, MTU路径发现等基于ICMP协议的功能可以工作
  8. DNS服务工作在53端口,所以我们接收来自源53端口的连接(如果你有DNS服务器的IP地址,那么我们可以用以下命令替换,只允许DNS server的IP地址发起的源端口53的报文,以达到更加安全的目的,假设DNS servers是1.1.1.1 and 1.1.2.1。
$IPT -A INPUT –s 1.1.1.1 -p udp --sport 53 -j ACCEPT 
$IPT -A INPUT –s 1.1.2.1 -p udp --sport 53 -j ACCEPT 
  1. 最后,我们只允许从自己主机主动发起的TCP连接里的TCP报文被接收。任何从外部来的主动发起的TCP连接请求都会被拒绝(deny
    TCP SYN 报文)。

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

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

相关文章

缓存雪崩问题

缓存雪崩&#xff1a;指在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量的请求到达数据库&#xff0c;带来巨大的压力 解决方案&#xff1a; 1.给不同的key的TTL添加随机值 2.利用redis集群提高服务的可用性 3.给缓存业务添加降级限流策略 4.给业务添…

扫雷,咱就是一扫一大片(C语言完美递归版)

&#x1f929;本文作者&#xff1a;大家好&#xff0c;我是paperjie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 &#x1f970;内容专栏&#xff1a;这里是《C语言》专栏&#xff0c;笔者用重金(时间和精力)打造&#xff0c;基础知识一网打尽&#xff0c;希望可以…

零基础入门 Stable Diffusion - 无需显卡把 AI 绘画引擎搬进家用电脑

我从小特别羡慕会画画的伙伴。他们能够将心中的想法画出来&#xff0c;而我最高水平的肖像画是丁老头。但在接触 Stable Diffusion 之后&#xff0c;我感觉自己脱胎换骨&#xff0c;给自己贴上了「会画画」的新标签。 丁老头进化旅程 Stable Diffusion 是一个「文本到图像」的…

区间预测 | MATLAB实现QRLSTM长短期记忆神经网络分位数回归时间序列区间预测

区间预测 | MATLAB实现QRLSTM长短期记忆神经网络分位数回归时间序列区间预测 目录 区间预测 | MATLAB实现QRLSTM长短期记忆神经网络分位数回归时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 进阶版 基础版 基本介绍 MATLAB实现QRLSTM长短期记忆神经…

微波方向有哪些SCI期刊推荐? - 易智编译EaseEditing

微波方向的SCI期刊推荐包括&#xff1a; IEEE Transactions on Microwave Theory and Technology&#xff1a; 该期刊是电磁场与微波技术领域的著名期刊&#xff0c;被世界上许多研究机构和大学广泛引用。 IEEE Transactions on Antennas and Propagation&#xff1a; 该期刊…

C++学习记录——이십일 AVL树

文章目录 1、了解AVL树2、模拟实现3、旋转1、左单旋2、右单旋3、双旋&#xff08;先左后右&#xff09;4、双旋&#xff08;先右后左&#xff09; 4、检查平衡5、测试性能&#xff08;随机数&#xff09;6、删除 1、了解AVL树 如果数据有序或接近有序&#xff0c;二叉搜索树将…

Java+Python+Paddle提取长文本文章中词频,用于Echart词云图数据

公司有个需求&#xff0c;就是需要提供给echart词云图的数据&#xff0c;放在以前我们的数据来源都是从产品那直接要&#xff0c;产品也是跑的别的接口&#xff0c;那怎么行呢&#xff0c;当然有自己的一套可以随便搞了&#xff0c;那么操作来了 Java package cn.iocoder.yud…

推荐几款2023年还在用的IDE工具

近期有不少刚学编程的小伙伴来问我&#xff0c;市面上那么多IDE工具&#xff0c;该怎么选&#xff1f;今天在这里跟大家分享几款个人比较钟爱的IDE工具&#xff0c;供大家参考。 Visual Studio 优点&#xff1a;支持多种语言&#xff0c;包括C#, C, Visual Basic等&#xff0c…

【Linux】进程信号“疑问?坤叫算信号吗?“

鸡叫当然也算信号啦~ 文章目录 前言一、认识信号量二、信号的产生 1.调用系统函数向进程发信号2.由软件条件产生信号3.硬件异常产生信号总结 前言 信号在我们生活中很常见&#xff0c;下面我们举一举生活中信号的例子&#xff1a; 你在网上买了很多件商品&#xff0c;再等待不…

【跟着陈七一起学C语言】今天总结:函数、数组、指针之间的关系

友情链接&#xff1a;专栏地址 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的错误&#x…

深度学习实战29-AIGC项目:利用GPT-2(CPU环境)进行文本续写与生成歌词任务

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下深度学习实战29-AIGC项目&#xff1a;利用GPT-2(CPU环境)进行文本续写与生成歌词任务。在大家没有GPU算力的情况&#xff0c;大模型可能玩不动&#xff0c;推理速度慢&#xff0c;那么我们怎么才能跑去生成式的模型…

14 KVM虚拟机配置-配置虚拟设备(其它常用设备)

文章目录 14 KVM虚拟机配置-配置虚拟设备&#xff08;其它常用设备&#xff09;14.1 概述14.2 元素介绍14.3 配置示例 14 KVM虚拟机配置-配置虚拟设备&#xff08;其它常用设备&#xff09; 14.1 概述 除存储设备、网络设备外&#xff0c;XML配置文件中还需要指定一些其他外部…

Python+selenium,轻松搭建 Web 自动化测试框架

在程序员的世界中&#xff0c;一切重复性的工作&#xff0c;都应该通过程序自动执行。「自动化测试」就是一个最好的例子。 随着互联网应用开发周期越来越短&#xff0c;迭代速度越来越快&#xff0c;只会点点点&#xff0c;不懂开发的手工测试&#xff0c;已经无法满足如今的…

云渲染靠谱吗,使用云渲染会不会被盗作品?

云渲染靠谱吗、安全吗&#xff1f;如果使用 云渲染会不会被盗作品......Renderbus瑞云渲染作为一个正经的云渲染平台&#xff0c;也时不时会收到这类疑问&#xff0c;首先&#xff0c;瑞云渲染是肯定靠谱的,各位可以放心使用。另外小编也将在本篇教你如何辨别云渲染平台是否安全…

通达信W底形态选股公式,也称双底形态

W底形态&#xff0c;也称双底形态&#xff0c;是一种经典的技术分析形态&#xff0c;代表了跌势的逆转。看起来像字母 "W"&#xff0c;描述了一波下跌&#xff0c;反弹&#xff0c;再次下跌到与上一波下跌相同或相近的位置&#xff0c;最后是另一波反弹。W底形态两次…

【细读Spring Boot源码】@ComponentScan是如何生效的?

前言 在使用SpringBoot使用过程中 RestController、Service、Repository这几个注解类上都标有Component注解 启动类上标有的SpringBootApplication注解类上有个ComponentScan注解。那么ComponentScan如何把相关的对象注册到BeanFactory的&#xff1f; 找到处理ComponentScan注…

【Qt 从入门到入土】下篇

【Qt 从入门到入土】上篇 一个非常好的学习 Qt 的视频 本文目录 6. 对话框QDialog6.1 基本概念6.2 标准对话框6.3 自定义消息框6.4 消息对话框6.5 标准文件对话框 7. 布局管理器7.1 系统提供的布局控件7.2 利用widget做布局 8. 常用控件8.1 QLabel 控件使用8.2 QLineEdit8.3 其…

1_5 pytorch操作

一、torch 算子 1、torch.nn.functional.affine_grid(theta, size) 给定一组仿射矩阵(theta)&#xff0c;生成一个2d的采样位置(流场)&#xff0c;通常与 grid_sample() 结合使用,用于空间仿射变换网络&#xff0c;用于对2D或3D数据进行仿射变换。 输入&#xff1a;theta(Te…

5.20 牛奶咖啡·仙羽「重生」巡回演唱会 武汉站 告白夜浪漫收官

牛奶咖啡主唱仙羽「重生」主题巡回演唱会将于2023年5月20日浪漫收官。经历多次延期&#xff0c;「重生」巡回演唱会武汉站 终于与大家见面&#xff0c;届时会为大家带来多首传唱度极高的歌曲&#xff0c;与歌迷朋友共度一个难忘的告白夜。 关于仙羽仙羽&#xff08;kiki&#…

微服务架构演变

微服务架构演变 认识微服务 服务架构演变 单体架构&#xff1a;将业务的所有功能集中在一个项目种开发&#xff0c;打成一个包部署 优点&#xff1a; 架构简单部署成本低 缺点&#xff1a; 耦合度高 分布式架构&#xff1a;根据业务功能对系统进行拆分&#xff0c;每个业…