tnblog
首页
视频
资源
登录

动态主机配置协议 DHCP (扩展OVS)

6100人阅读 2022/5/25 13:45 总访问:3465021 评论:0 收藏:0 手机
分类: 容器编排

Kubernetes

动态主机配置协议 DHCP

DHCP简介


动态主机设置协议(英语:Dynamic Host Configuration Protocol,缩写:DHCP),又称动态主机组态协定,是一个用于IP网络的网络协议,位于OSI模型的应用层,使用 DHCP 协议工作,主要有两个用途:

—用于内部网或网络服务供应商自动分配IP地址给用户
—用于内部网管理员对所有电脑作中央管理

DHCP 用一台或一组 DHCP 服务器来管理网络参数的分配,这种方案具有容错性。即使在一个仅拥有少量机器的网络中,DHCP 仍然是有用的,因为一台机器可以几乎不造成任何影响地被增加到本地网络中。

甚至对于那些很少改变地址的服务器来说,DHCP 仍然被建议用来设置它们的地址。如果服务器需要被重新分配地址的时候,就尽可能不去做更改。对于一些设备,如路由器和防火墙,则不应使用DHCP。

DHCP 也可用于直接为服务器和桌面计算机分配地址,并且透过一个 PPP 代理,也可为拨接及宽带的主机,以及住宅 NAT 网关和路由器分配地址。DHCP 一般不适用于使用在无边际路由器和 DNS 服务器上。

更多细节

  • DHCP是在BOOTP(Bootstrap Protocol)基础上发展而来,但BOOTP运行在相对静态(每台主机都有固定的网络连接)的环境中,管理员为每台主机配置专门的BOOTP参数文件,该文件会在相当长的时间内保持不变。DHCP从以下两方面对BOOTP进行了扩展:
    1. DHCP允许计算机动态地获取IP地址,而不是静态为每台主机指定地址。
    2. DHCP能够分配其他配置参数,例如客户端的启动配置文件,使客户端仅用一个消息就获取它所需要的所有配置信
      息。
      DHCP协议由RFC 2131定义,采用客户端/服务器通信模式,由客户端(DHCP Client)向服务器(DHCP Server)
      提出配置申请,服务器返回为客户端分配的配置信息。
      DHCP可以提供两种地址分配机制,网络管理员可以根据网络需求为不同的主机选择不同的分配策略。
  • 动态分配机制:通过DHCP为主机分配一个有使用期限(这个使用期限通常叫做租期)的IP地址。
    这种分配机制适用于主机需要临时接入网络或者空闲地址数小于网络主机总数且主机不需要永久连接网络的场景。
  • 静态分配机制:网络管理员通过DHCP为指定的主机分配固定的IP地址。
    相比手工静态配置IP地址,通过DHCP方式静态分配机制避免人工配置发生错误,方便管理员统一维护管理。
    DHCP受益主要有以下两点:
    1. 降低客户端的配置和维护成本
      DHCP易配置部署,对于非技术用户,DHCP能够将客户端与配置相关的操作降至最低,并能够降低远程部署和维
      护成本。
    2. 集中管理
      DHCP服务器可以管理多个网段的配置信息,当某个网段的配置发生变化时,管理员只需要更新DHCP服务器上的
      相关配置即可。

租期

DHCP服务器给每个分配给客户端的IP地址定义一个使用期限,该使用期限被称为租期。在租期到期前,DHCP客户端
如果仍需要使用该IP地址,可以请求延长租期;如果不需要,可以主动释放该IP地址。在没有其他空闲地址可用的情
况下,DHCP服务器会把客户端主动释放的IP地址分配给其他客户端。
DHCP服务器动态分配的所有IP地址都受租期时长的限制,不同的DHCP服务器配置的租期时长可以不同。静态分配的
IP地址不受租期时长的限制,使用期限为无限长。
DHCP客户端不会等到租期到期后再申请IP地址,这样会导致IP地址被服务器回收,然后分配给其他客户端。为保证能
够使用原来的IP地址,客户端会在租期到期前的某个时间点就开始申请延长租期。

地址池

地址池指的是DHCP服务器可以为客户端分配的所有IP地址的集合。除IP地址外,地址池内还可以配置租期、子网掩码、
默认网关等网络参数。在DHCP服务器为客户端分配IP地址时,这些网络参数也一并分配给客户端。
根据创建方式的不同,地址池可以分为基于接口方式的地址池和基于全局方式的地址池。

  • 基于接口方式的地址池:在DHCP服务器与客户端相连的接口上配置IP地址,地址池是跟此接口地址所属同一网段
    的IP地址,且地址池中地址只能分配给此接口下的客户端。这种配置方式简单,仅适用于DHCP服务器与客户端在
    同一个网段的场景。
  • 基于全局方式的地址池:在系统视图下创建指定网段的地址池,且地址池中地址可以分配给设备所有接口下的客户
    端。当DHCP服务器与客户端不在同一个网段时,需要部署DHCP中继。

    DHCP服务器依据是否部署DHCP中继来选择地址池。无DHCP中继场景下,DHCP服务器选择与接收DHCP请求报文
    的接口IP地址处于同一网段的地址池。有DHCP中继场景下,DHCP服务器选择与DHCP请求报文中giaddr字段(标识
    客户端所在网段)位于同一网段的地址池。
    根据客户端的数量和接入断开的时间、频率来确定地址池内需要部署的IP地址数量。
    根据IP地址的使用情况,地址池中的IP地址可以分为多种状态。

经典网络


一般的网络结构如下:


DHCP服务器

DHCP服务器负责从地址池中选择IP地址分配至DHCP客户端,还可以为DHCP客户端提供其他网络参数,如默认网关地址、
DNS服务器地址和WINS服务器地址。DHCP服务器可以接收处理来自本网段或跨网段由DHCP中继转发的DHCP请求报文。

DHCP客户端

DHCP客户端发送DHCP请求报文、通过BOOTP或DHCP协议请求获取IP地址等网络参数的设备。例如,IP电话、PC、手机、无
盘工作站等。

DHCP中继

DHCP中继负责转发DHCP服务器和DHCP客户端之间的DHCP报文,协助DHCP服务器向DHCP客户端动态分配网络参数的设备。
DHCP客户端广播发送请求报文(即目的IP地址为255.255.255.255),位于同一网段内的DHCP服务器能够接收请求报文。如果
DHCP客户端和DHCP服务器不在同一个网段,DHCP服务器无法接收来自客户端的请求报文,此时,需要通过DHCP中继来转发
DHCP报文。不同于传统的IP报文转发,DHCP中继接收到DHCP请求或应答报文后,会重新修改报文格式并生成一个新的DHCP
报文再进行转发。

报文分析


我们通过winshark来抓取DHCP的包。


从这上面我们可以发现有4种不同类型的包,但其实有8种类型。

类型 描述
DHCP DISCOVER DHCP客户端首次登录网络时进行DHCP交互过程发送的第一个报文,用来寻找DHCP服务器。
DHCP OFFER DHCP服务器用来响应DHCP DISCOVER报文,此报文携带了各种配置信息。
DHCP REQUEST 此报文用于以下三种用途。
1.客户端初始化后,发送广播的DHCP REQUEST报文来回应服务器的DHCP OFFER报文。
2.客户端重启后,发送广播的DHCP REQUEST报文来确认先前被分配的IP地址等配置信息。
3.当客户端已经和某个IP地址绑定后,发送DHCP REQUEST单播或广播报文来更新IP地址的租约。
DHCP ACK 服务器对客户端的DHCP REQUEST报文的确认响应报文,客户端收到此报文后,才真正获得了IP地址和相关的配置信息。
DHCP NAK 服务器对客户端的DHCP REQUEST报文的拒绝响应报文,例如DHCP服务器收到DHCP REQUEST报文后,没有找到相应的租约记录,则发送DHCP NAK报文作为应答,告知DHCP客户端无法分配合适IP地址。
DHCP DECLINE 当客户端发现服务器分配给它的IP地址发生冲突时会通过发送此报文来通知服务器,并且会重新向服务器申请地址。
DHCP RELEASE 客户端可通过发送此报文主动释放服务器分配给它的IP地址,当服务器收到此报文后,可将这个IP地址分配给其它的客户端。
DHCP INFORM DHCP客户端获取IP地址后,如果需要向DHCP服务器获取更为详细的配置信息(网关地址、DNS服务器地址),则向DHCP服务器发送DHCP INFORM请求报文。


DHCP报文中各个字段的含义:

字段 长度 含义
op (op code) 1字节 表示报文的类型,取值为1或2,含义如下:
1:客户端请求报文
2:服务器响应报文
htype (hardware type) 1字节 表示硬件类型。不同的硬件类型取值不同,最常见的值是1,表示以太网(10Mb)。
hlen (hardware length) 1字节 表示硬件地址长度,以太网的值为6。
hops 1字节 表示当前的DHCP报文经过的DHCP中继的数目。该字段由客户端或服务器设置为0,每经过一个DHCP中继时,该字段加1。此字段的作用是限制DHCP报文.所经过的DHCP中继数目。服务器和客户端之间的DHCP中继数目不能超过16个,也就是Hops值不能大于16,否则DHCP报文将被丢弃。
xid 4字节 表示DHCP客户端选取的随机数,使DHCP服务器的回复与DHCP客户端的报文相关联。
secs (seconds) 2字节 表示客户端从开始获取地址或地址续租更新后所用的时间,单位是秒。
flags 2字节 表示标志字段。只有标志字段的最高位才有意义,其余的15位均被置为0。最高位被解释为单播或者广播响应标志位,内容如下所示:
0:客户端请求服务器以单播形式发送响应报文
1:客户端请求服务器以广播形式发送响应报文
ciaddr (client ip address) 4字节 表示客户端的IP地址。可以是服务器分配给客户端的IP地址或者客户端已有的IP地址。客户端在初始化状态时没有IP地址,此字段为0.0.0.0。IP地址0.0.0.0仅在采用DHCP方式的系统启动时允许本主机利用它进行临时的通信,不是有效目的地址。
yiaddr (your client ip address) 4字节 表示服务器分配给客户端的IP地址。当服务器进行DHCP响应时,将分配给客户端的IP地址填入此字段。
siaddr (server ip address) 4字节 DHCP客户端获得启动配置信息的服务器的IP地址。
giaddr(gateway ip address) 4字节 表示第一个DHCP中继的IP地址。当客户端发出DHCP请求时,如果服务器和客户端不在同一个网段,那么第一个DHCP中继在将DHCP请求报文转发给DHCP服务器时,会把自己的IP地址填入此字段,DHCP服务器会根据此字段来判断出客户端所在的网段地址,从而选择合适的地址池,为客户端分配该网段的IP地址。
服务器还会根据此地址将响应报文发送给此DHCP中继,再由DHCP中继将此报文转发给客户端。
若在到达DHCP服务器前经过了多个DHCP中继,该字段作为客户端所在的网段的标记,填充了第一个DHCP中继的IP地址后不会再变更,只是每经过一个DHCP中继,hops字段的数值会加1。
chaddr (client hardware address) 16字节 表示客户端的MAC地址,此字段与前面的hardware typehardware length保持一致。当客户端发出DHCP请求时,将自己的硬件地址填入此字段。对于以太网,当hardware typehardware length分别为16时,此字段必须填入6字节的以太网MAC地址。
sname (server host name) 64字节 表示客户端获取配置信息的服务器名字。此字段由DHCP服务器填写,是可选的。如果填写,必须是一个以0结尾的字符串。
file (file name) 128字节 表示客户端需要获取的启动配置文件名。此字段由DHCP服务器填写,随着DHCP地址分配的同时下发至客户端。本字段是可选的,如果填写,必须是一个以0结尾的字符串。
options 可变 表示DHCP的选项字段,最多为312字节。DHCP通过此字段包含了DHCP报文类型,服务器分配给终端的配置信息,如网关IP地址,DNS服务器的IP地址,客户端可以使用IP地址的有效租期等信息。

DHCP代理[OpenStack]


大致所使用的流程如下:

使用Dnsmasq进程实现DHCP

  1. # 使用 ovs bridge 连接 DHCP namespace interface。
  2. interface_driver =neutron.agent.linux.interface.OVSInterfaceDriver
  3. # 当创建 network 并在 subnet 上 enable DHCP 时,网络节点上的 DHCP agent 会启动一个 dnsmasq 进程为该 network 提供 DHCP 服务。
  4. # 查看Controller上的DHCP Agent 进程
  5. ps -ef | grep dnsmasq

  1. # 查看子网
  2. neutron subnet-list
  3. ip netns
  4. # 查看DHCP Agent的TAP
  5. ip netns exec qdhcp-e2027b43-f621-4da7-ae24-fc59c5894ebe ip a
  6. # 查看ovs bridge上的dhcp server tap设备
  7. ovs-vsctl show
  8. # 当虚机孵化完成以后,此时虚机开机发起dhcp的discover消息,位于同一个vlan的都可以收到此广播消息


在创建 instance 时,Neutron 会为其分配一个 port,里面包含了 MAC 和 IP 地址信息。这些信息会同步更新到 dnsmasq 的 host 文件,所以我们会看到有read的动作。

DHCP - Docker


当Docker以桥接的方式启动容器时,容器内部的IP是经过DHCP获取的,例如:172.17.0.2/16,且每重启依次IP都会发生变动。

安装环境

  1. # 拉取
  2. sudo docker pull networkboot/dhcpd
  3. # 安装openswatch
  4. yum install -y https://www.rdoproject.org/repos/rdo-release.rpm
  5. sudo yum install openvswitch libibverbs -y
  6. sudo systemctl enable --now openvswitch
  7. # 安装ovs-docker
  8. wget http://github.com/openvswitch/ovs/raw/master/utilities/ovs-docker
  9. chmod +x ovs-docker
  10. mv ovs-docker /usr/bin/

模拟实践


接下来我们通过一台容器DHCP服务器,和三台ovs的交换机,与三台连接不同交换机的容器主机。


首先生成交换机vswitch0、vswitch1、vswitch2

  1. sudo ovs-vsctl add-br vswitch0
  2. sudo ovs-vsctl add-br vswitch1
  3. sudo ovs-vsctl add-br vswitch2


创建veth pair v1与v2,并激活

  1. sudo ip link add v1 type veth peer name v2
  2. # 激活
  3. sudo ip link set dev v1 up
  4. sudo ip link set dev v2 up


给v1配置ip及子网掩码

  1. sudo ifconfig v1 192.168.1.254 netmask 255.255.255.0


创建DHCP服务器,监听v1 ,挂载本地data文件夹,data里面中只有dhcpd.conf文件。

  1. mkdir -p ~/emxbook/docker-dhcpd/data
  2. vim ~/emxbook/docker-dhcpd/data/dhcpd.conf
  3. sudo docker run -it \
  4. --rm --net host \
  5. --init \
  6. --name=dhcpServer1 \
  7. -v ~/emxbook/docker-dhcpd/data:/data \
  8. networkboot/dhcpd v1


dhcpd.conf配置内容如下:

  1. subnet 192.168.1.0 netmask 255.255.255.0 {
  2. option routers 192.168.1.1;
  3. option subnet-mask 255.255.255.0;
  4. option domain-name "emx.local";
  5. option domain-name-servers 8.8.8.8;
  6. range 192.168.1.2 192.168.1.100;
  7. }


将v2连接到交换机上。

  1. sudo ovs-vsctl add-port vswitch0 v2


让交换机vswitch0、vswitch1、vswitch2彼此相连。

  1. sudo ovs-vsctl add-port vswitch0 s0p0
  2. sudo ovs-vsctl set Interface s0p0 type=patch
  3. sudo ovs-vsctl set Interface s0p0 options:peer=s1p1
  4. sudo ovs-vsctl add-port vswitch1 s1p1
  5. sudo ovs-vsctl set Interface s1p1 type=patch
  6. sudo ovs-vsctl set Interface s1p1 options:peer=s0p0
  7. sudo ovs-vsctl add-port vswitch0 s0p1
  8. sudo ovs-vsctl set Interface s0p1 type=patch
  9. sudo ovs-vsctl set Interface s0p1 options:peer=s2p1
  10. sudo ovs-vsctl add-port vswitch2 s2p1
  11. sudo ovs-vsctl set Interface s2p1 type=patch
  12. sudo ovs-vsctl set Interface s2p1 options:peer=s0p1


创建主机h1、h2、h3,并将其连接到交换机上,其中ubunut:5是添加了基本net-tools、isc-dhcp-client,创建的时候记得使用--cap-add=NET_ADMIN

  1. sudo docker run -itd --network=none --name=h1 --cap-add=NET_ADMIN burlyluo/nettoolbox
  2. sudo docker run -itd --network=none --name=h2 --cap-add=NET_ADMIN burlyluo/nettoolbox
  3. sudo docker run -itd --network=none --name=h3 --cap-add=NET_ADMIN burlyluo/nettoolbox
  4. sudo ovs-docker add-port vswitch0 eth1 h1
  5. sudo ovs-docker add-port vswitch1 eth1 h2
  6. sudo ovs-docker add-port vswitch2 eth1 h3


可以使用floot-light控制交换机vswitch0、vswitch1、vswitch2交换机(选择)

  1. sudo ovs-vsctl set-controller vswitch0 tcp:127.0.0.1:6653
  2. sudo ovs-vsctl set-controller vswitch1 tcp:127.0.0.1:6653
  3. sudo ovs-vsctl set-controller vswitch2 tcp:127.0.0.1:6653


接着我们进入每一个容器,执行dhclient eth1来获取客户端的ip地址。最后ping 测试一下完全没问题。

  1. docker exec -it h1 /bin/bash
  2. ifconfig
  3. dhclient eth1
  4. ifconfig


当然我们还可以抓包尝试。

Trunk端口

Trunk简介


这个端口是交换机之间或者交换机和上层设备之间的通信端口,用于干道链路。这种端口的存在就是为了多个vlan的跨越交换机进行传递。
一个trunk端口可以拥有一个主vlan和多个副vlan。
在交换机之间传递tagged frame。允许多个VLAN通过,可以与PVID不同;
收到不带tagged frame的数据帧时,打上主PVID 并转发;
收到带tagged frame数据帧时,检查VLAN ID,如果允许并且VLAN ID与PVID相同,去掉tagged直接转发,如果允许并且VLAN ID与PVID不同,直接转发原数据帧。

简单来讲:可以同时传输多个VLAN,只在两个交换机之间配置trunk。

  1. # 使用docker创建四个不带网卡的容器
  2. docker run -itd --network=none --name=vm01 --privileged centos:7 /bin/bash
  3. docker run -itd --network=none --name=vm02 --privileged centos:7 /bin/bash
  4. docker run -itd --network=none --name=vm03 --privileged centos:7 /bin/bash
  5. docker run -itd --network=none --name=vm04 --privileged centos:7 /bin/bash
  6. # 创建OVS网桥
  7. ovs-vsctl add-port vswitch0
  8. ovs-vsctl add-port vswitch1
  9. # 使用ovs-docker工具给容器添加网卡到ovs网桥
  10. ovs-docker add-port vswitch0 eth0 vm01 --ipaddress=192.168.1.2/24
  11. ovs-docker add-port vswitch1 eth0 vm02 --ipaddress=192.168.1.3/24
  12. ovs-docker add-port vswitch0 eth0 vm03 --ipaddress=192.168.1.4/24
  13. ovs-docker add-port vswitch1 eth0 vm04 --ipaddress=192.168.1.5/24
  14. # 链接vswitch0和vswitch1
  15. ovs-vsctl add-port vswitch0 patch_to_vswitch1
  16. ovs-vsctl add-port vswitch1 patch_to_vswitch0
  17. ovs-vsctl set interface patch_to_vswitch1 type=patch
  18. ovs-vsctl set interface patch_to_vswitch0 type=patch
  19. ovs-vsctl set interface patch_to_vswitch0 options:peer=patch_to_vswitch1
  20. ovs-vsctl set interface patch_to_vswitch1 options:peer=patch_to_vswitch0
  21. # 查看配置情况
  22. ovs-vsctl show
  23. # 查看所对应的容器ID
  24. ovs-vsctl list interface <xxxx> | grep container_id
  25. ovs-vsctl list interface <xxxx> | grep container_id
  26. ovs-vsctl list interface <xxxx> | grep container_id
  27. ovs-vsctl list interface <xxxx> | grep container_id
  28. # 找出相关vm所对应的id
  29. vm01 tag 100
  30. vm02 tag 100
  31. vm03 tag 200
  32. vm04 tag 200
  33. # 打上相关tag标签
  34. ovs-vsctl set port 8e1d9abd3ab64_l tag=100
  35. ovs-vsctl set port 1cc95bf649264_l tag=100
  36. ovs-vsctl set port c6df4ef55f864_l tag=200
  37. ovs-vsctl set port 5be29191e0a14_l tag=200
  38. # 设置网桥之间的patch端口的vlan模式为trunk
  39. ovs-vsctl set port patch_to_vswitch1 VLAN_mode=trunk
  40. ovs-vsctl set port patch_to_vswitch0 VLAN_mode=trunk
  41. ovs-vsctl set port patch_to_vswitch0 trunk=100,200
  42. ovs-vsctl set port patch_to_vswitch1 trunk=100,200
  43. # 测试Trunk
  44. ovs-ctl set port patch_to_vswitch0 trunk=200
  45. ovs-vsctl set port patch_to_vswitch1 trunk=200
  46. # 查看flow table
  47. ovs-ofctl dump-flows vswitch0

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

扩展ef自动映射需要查询的字段(表达式树Expression),动态构建返回值

Entity Framework 动态构造select表达式比如我们需要返回某些字段会采用如下的写法但是发现每次都去写select如果字段很多不...

扩展mvc实现model直接传递匿名对象

如果我们直接通过model传递匿名对象,是不行滴后台通过model传递一个匿名对象publicActionResultIndex() { returnView(ne...

根据委托和lamdba表达式扩展方法

lamdba表达式ForEach扩展方法:public static void GetForEach&lt;T&gt;(this IEnumerable&lt;T&gt; list, Action&lt;T&gt;...

表达式树+反射扩展EF实现动态排序。List动态排序

我们在显示表格的时候经常会在点击表头的时候实现排序,当然很多前端的框架都实现了当前页的页面排序,直接配置一下就行了...

推荐Visual Studio好用的扩展插件(不定时更新)

嗨咯,大家好。什么是扩展?扩展是可以允许你在 Visual Studio 中进行自定义并增强在其中的体验的附加项,通过添加新功能或...

EF扩展反射实现动态排序+表达式树

现在各种网站上的表格可以通过点击排头来实现排序例如:今天我就来一探究竟,这是怎么实现的呢?具体步骤:我通过写扩展方...

表达式树+反射+扩展方法实现动态排序效果

后台代码如下:方法1:逐个判断 --&gt;缺点:代码重复,体验感差 if(sort.ToLower()==&quot;max&quot;) { if(sortway==...

.net Core3.0在Ubuntu 16.04上面的部署(Supervisor+nginx)(扩展docker)

前 言Linux 随着Linux越来越流行,本人一个.net程序员也多次研究linux与.net的相关产品,以及中间件的使用方式。So今天给...

字符串扩展方法

获取字符串的实际长度(按单字节) publicstaticintGetRealLength(thisstringsource) { returnSystem.Text.Encoding.Defau...

验证合法性扩展方法

Email格式是否合法 publicstaticboolIsEmail(thisstringsource) { returnRegex.IsMatch(source,@&quot;^\w+((-\w+)|(\.\...

扩展markdown增加mermaid支持画图

我看网上没有什么资料,只有说怎么去用它,没有说怎么才能用它。那就自己慢慢研究在让markdown支持,要自己实现这个必须要...

c扩展方法简单介绍

可以不用继承就可以给一个类增加方法!语法: Public static class 类名 { //你想添加的扩展方法 Public static ...

list扩展方法ForEach原理(where,FirstOrDefault同理!)

//ForEach的原理就是使用循环 //委托使用循环 publicstaticvoidMyForEach&lt;T&gt;(thisList&lt;T&gt;item,Action&lt;T...

特性扩展实体对象验证、枚举验证值是否正确

如果实体属性字段过多,几十,上百个,如果我们每个字段都去判断的话很麻,代码量很大,我们可以采用特性加枚举进行验证:1、...

Mybatis的SQL构建7 小小扩展+springboot

pom.xml的依赖,我是直接在spring.io官方下的,这样避免依赖冲突&lt;!--jdbc--&gt; &lt;dependency&gt; &lt;groupId&gt;o...
这一世以无限游戏为使命!
排名
2
文章
633
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术