剖析ironic
关键技术
在安装操作系统时需要存储介质来存储系统镜像、需要控制物理机开关机,在网络部署环境中还需要预启动环境。
- PXE (预启动环境)
- IPMI(电源管理)
- iSCSI(存储)
什么是PXE
PXE(preboot execute environment) 预启动执行环境。PXE 是目前主流的无盘启动技术,它可以使计算机通过网络而不是从本地硬盘、光驱等设备启动,采用Client/Server的网络模式,在启动过程中,终端要求服务器分配IP地址,再用TFTP(trivial file transfer protocol)或MTFTP(multicast trivial file transfer protocol)协议下载一个启动软件包到本机内存中执行,由这个启动软件包完成终端基本软件设置,从而引导预先安装在服务器中的终端操作系统。
利用 PXE 进行系统安装需要被安装的主机上有 PXE 支持的网卡,不过现在的网卡一般都内嵌支持 PXE 的 ROM 芯片。当计算机引导时,BIOS 首先会把 PXE Client 调入内存中执行,PXE Client 被载入内存后,它便同时具有 DHCP client 和 TFTP Client 的功能,DHCP client 会向 DHCP server 请求 ip 分配给将要安装系统的主机,然后由 PXE Client 将放置在远端的文件通过 TFTP 下载到本地运行。
安装流程如下:
- 客户机从自己的PXE网卡启动,向本网络中的DHCP服务器索取IP,并搜寻引导文件的位置
- DHCP服务器返回分给客户机IP以及NBP(Network Bootstrap Program )文件的放置位置(该文件一般是放在一台TFTP服务器上)
- 客户机向本网络中的TFTP服务器索取NBP
- 客户机取得NBP后之执行该文件
- 根据NBP的执行结果,通过TFTP服务器加载内核和文件系统
- 安装操作系统
PXE能提供操作系统镜像,但是如何远程开机呢,这件事就是由IPMI来做的。
什么是IPMI
智能平台管理接口(IPMI:Intelligent Platform Management Interface)是一项应用于服务器管理系统设计的标准,提供管理和监控CPU、固件(BIOS、UEFI)和操作系统等功能,由Intel、HP、Dell和NEC公司于1998年共同提出。利用此接口标准设计有助于在不同类服务器系统硬件上实施系统管理,使不同平台的集中管理成为可能,目前有超过200家公司支持IPMI。IPMI信息通过网络连接到基板管理控制器 (BMC)进行交流,不依赖BOIS或者操作系统,这使得在操作系统不响应或未加载的情况下其仍然可以进行开关机、信息提取等操作。Ironic 正是利用此技术可以远程的对裸机进行上下电或者其他操作,而不是依赖物理开关或者操作系统。
IPMI可以在操作系统启动之前、管理系统启动之前、操作系统或者管理系统失败(与带内系统管理的最大特性)时对物理机进行管理,利用IPMI可以实现以下功能:
- 可以在服务器通电(没有启动操作系统)情况下,对它进行远程管理:开机,关机,重启
- 基于文本的控制台重定向,可以远程查看和修改BIOS设置,系统启动过程,登入系统等
- 可以远程通过串口IP映射(SoL)连接服务器,解决ssh服务无法访问,远程安装系统,查看系统启动故障等问题
- 可以通过系统的串行端口进行访问
- 故障日志记录和 SNMP 警报发送,访问系统事件日志 (System Event Log ,SEL) 和传感器状况
IPMI技术功能点总结:
- 远程电源控制 (on / off / cycle / status)
- 串口的IP映射 Serial over LAN (SoL)
- 支持健康关机(Graceful shutdown support)
- 机箱环境监控 (温度, 风扇转速, CPU电压等)
- 远程设备身份LED控制(Remote ID LED control)
- 系统事件日志(System event log)
- 平台事件跟踪(Platform Event Traps)
- 数据记录(Data logging)
- 虚拟KVM会话(Virtual KVM)
- 虚拟媒介(Virtual Media)
参考资料: https://en.wikipedia.org/wiki/Intelligent_Platform_Management_Interface
什么是iSCSI
iSCSI是一个指令集,iSCSI技术是一种新储存技术,该技术是将现有SCSI接口与以太网络(Ethernet)技术结合,使服务器可与使用IP网络的储存装置互相交换资料。
早期的企业使用的服务器若有大容量磁盘的需求时,通常是透过SCSI来串接SCSI磁盘,因此服务器上面必须要加装SCSI卡,而且这个SCSI是专属于该服务器的。 后来这个外接式的SCSI设备被SAN的架构所取代,在SAN的标准架构下,虽然有很多的服务器可以对同一个SAN 进行存取的动作,不过为了速度需求,通常使用的是光纤通道。但是光纤通道很贵,不但设备贵,服务器上面也要有光纤卡,很麻烦,所以光纤的SAN在中小企业很难普及。
后来网络实在太普及,尤其是以IP封包为基础的LAN技术已经很成熟,再加上以太网路的速度越来越快,所以就有厂商将SAN的连接方式改为利用IP技术来处理。 然后再透过一些标准的设定,最后就得到Internet SCSI (iSCSI)这个的产生! iSCSI主要是透过TCP/IP的技术,将储存设备端透过iSCSI target (iSCSI目标端)功能,做成可以提供磁盘的服务器端,再透过iSCSI initiator (iSCSI初始化用户)功能,做成能够挂载使用iSCSI target的用户端,如此便能透过iSCSI设置来进行磁盘的应用了。
也就是说,iSCSI 这个架构主要将储存装置与使用的主机分为两个部分,分别是:
- iSCSI target:就是储存设备端,存放磁盘或RAID的设备,目前也能够将Linux主机模拟成iSCSI target了! 目的在提供其他主机使用的磁盘。
- iSCSI initiator:就是能够使用target的用户端,通常是服务器。 也就是说,想要连接到iSCSI target的服务器,也必须要安装iSCSI initiator的相关功能后才能够使用iSCSI target提供的磁盘。
ironic内部技术
ironic代码结构
下面是ironic liberty版的代码结构,其中省略了部分文件
ironic-stable-liberty:.
│
│ babel.cfg
│ CONTRIBUTING.rst
│ driver-requirements.txt
│ LICENSE
│ MANIFEST.in
│ openstack-common.conf
│ README.rst
│ RELEASE-NOTES
│ requirements.txt
│ setup.cfg #pbr的配置文件
│ setup.py
│ test-requirements.txt
│ tox.ini #tox配置文件
│ vagrant.yaml
│ Vagrantfile
│
├─doc #文档
│
├─etc #相关配置文件
│
├─ironic
│ │
│ ├─api #api,使用peach框架
│ │ │ acl.py
│ │ │ app.py #API入口
│ │ │ app.wsgi
│ │ │ config.py
│ │ │ expose.py
│ │ │ hooks.py
│ │ │ __init__.py
│ │ │
│ │ ├─controllers #控制器
│ │ │ │ base.py
│ │ │ │ link.py
│ │ │ │ root.py #API总控制器
│ │ │ │ __init__.py
│ │ │ │
│ │ │ └─v1 #v1 版本API
│ │ │
│ │ └─middleware
│ │
│ ├─cmd # 服务入口
│ │ api.py
│ │ conductor.py
│ │ dbsync.py
│ │ __init__.py
│ │
│ ├─common 常用方法
│ │
│ ├─conductor
│ │ manager.py
│ │ rpcapi.py
│ │ task_manager.py
│ │ utils.py
│ │ __init__.py
│ │
│ ├─db #数据库相关,包括sqlalchemy、alembic
│ │
│ ├─dhcp #neutron dhcp api
│ │ base.py
│ │ neutron.py
│ │ none.py
│ │ __init__.py
│ │
│ ├─drivers #驱动相关
│ │ │ agent.py #agent_* 驱动
│ │ │ base.py
│ │ │ drac.py #drac驱动
│ │ │ fake.py
│ │ │ ilo.py #ilo驱动,惠普的
│ │ │ irmc.py #irmc
│ │ │ pxe.py #pxe_* 驱动
│ │ │ raid_config_schema.json
│ │ │ utils.py
│ │ │ __init__.py
│ │ │
│ │ └─modules #驱动的具体方法
│ │
│ │
│ ├─locale #翻译
│ │
│ ├─nova #nova相关,这里包括与Nova computer冲突的临时解决办法
│ │
│ ├─objects #基本对象的方法,包括conducotr、node、port、field、chassis
│ │
│ ├─openstack #openstack相关的,这里包含处理镜像的方法的帮助函数
│ │
│ └─tests #测试相关
│
│
├─releasenotes #发布历史
│
└─tools #相关工具
API
ironic-api提供一系列接口,详见ironic API。
- 节点相关(node)
- 节点增删改查(List, Searching, Creating, Updating, and Deleting)
- 合法性检查
- 设置和清除维修状态
- 设置和获取boot device
- 获取节点当前综合信息,包括power, provision, raid, console等
- 更改电源状态
- 更改节点提供状态( manage, provide, inspect, clean, active, rebuild, delete (deleted), abort)
- 设置RAID
- 启动、停止、获取console
- 查看、调用厂商定制方法(passthru方法)
- 端口相关(Port)
- 对物理端口(Port)的增删改查(Listing, Searching, Creating, Updating, and Deleting ),新建的时候就要指定端口的物理地址(一般是MAC地址)与Node进行绑定。
- 查看与Node连接的端口
- 驱动相关(driver)
- 列举所有驱动
- 查看驱动的详细信息、属性
- 查看和调用厂商的驱动
- Chassis(机箱,一组node的集合)
- 增删改查
Chassis这个资源类型是为了给节点分组用的,目前只有列举一组节点的功能。不赞成使用这个类型,将来可能会去除掉。
- 增删改查
Conductor
Ironic-Conductor是Ironic中最主要的模块,通过Ironic-API对外提供功能,与Ironic-API之间通过RPC进行通信,负责绝大部分工作,包括与Neutron通信为物理机配置网络信息,与Glance通信获取镜像,与Cinder和Swift通信进行为物理机提Ironic-Conductor是Ironic中最主要的模块,通过Ironic-API对外提供功能,与Ironic-API之间通过RPC进行通信,负责绝大部分工作,包括与Neutron通信为物理机配置网络信息,与Glance通信获取镜像,与Cinder和Swift通信进行为物理机提供存储。 供存储。
同时控制着物理机状态的改变过程,下图是openstack Liberty中物理机状态转换图:
在高可用方面,conductor 采用一致性哈希算法保证Condutor节点新增退出时不影响Bare metal节点。
DB
采用MySQL,存储物理机和驱动的状态信息,可以换成其他数据库。
Drivers
驱动是真正操作物理机的模块,Ironic的驱动以插件形式设计,厂商可以实现自己的驱动来为自己的设备提供特色化功能。实现自己的驱动只需要实现几个相关的方法即可。
驱动架构
驱动有不同的属性,每个属性能够完成一定的功能,这些属性分为三种接口:
- 核心接口(core),最基本的功能,是其他服务的依赖,所有驱动都必须实现的,包括power,deploy.
- 标准接口(standard),实现通用功能,主要包括 management, console, boot, inspect, raid.
- 厂商接口(vendor),提供个性化功能
接口功能:
分类 | 接口 | 功能 | 主要需要实现的方法 |
---|---|---|---|
core | power | 管理电源 | get_properties、validate、 get_power_state、set_power_state、reboot |
deploy | 部署方式 | get_properties、validate、 deploy、tear_down、prepare、clean_up、take_over、prepare_cleaning、tear_down_cleaning | |
standard | console | 通过硬件得到物理机的控制台 | get_properties、validate、start_console、stop_console、get_console |
management | 管理物理机硬件 | get_properties、validate、get_supported_boot_device、set_boot_device、get_boot_device 、get_sensors_data | |
boot | 启动相关的动作 | get_properties、validate、prepare_ramdisk、clean_up_ramdisk、prepare_instance、clean_up_instance | |
inspect | 硬件自检,主要检查内存、CPU、本地分区 | inspect_hardware | |
raid | 设置raid | get_properties、validate、 create_configuration、delete_configuration、get_logical_disk_properties | |
vendor | 厂商的自定义功能 | get_properties、validate、... |
驱动架构示意图:
Liberty支持的驱动,在setup.cfg中可以看到
agent_ilo = ironic.drivers.ilo:IloVirtualMediaAgentDriver
agent_ipmitool = ironic.drivers.agent:AgentAndIPMIToolDriver
agent_irmc = ironic.drivers.irmc:IRMCVirtualMediaAgentDriver
agent_pyghmi = ironic.drivers.agent:AgentAndIPMINativeDriver
agent_ssh = ironic.drivers.agent:AgentAndSSHDriver
agent_vbox = ironic.drivers.agent:AgentAndVirtualBoxDriver
agent_ucs = ironic.drivers.agent:AgentAndUcsDriver
iscsi_ilo = ironic.drivers.ilo:IloVirtualMediaIscsiDriver
iscsi_irmc = ironic.drivers.irmc:IRMCVirtualMediaIscsiDriver
pxe_ipmitool = ironic.drivers.pxe:PXEAndIPMIToolDriver
pxe_ipminative = ironic.drivers.pxe:PXEAndIPMINativeDriver
pxe_ssh = ironic.drivers.pxe:PXEAndSSHDriver
pxe_vbox = ironic.drivers.pxe:PXEAndVirtualBoxDriver
pxe_seamicro = ironic.drivers.pxe:PXEAndSeaMicroDriver
pxe_iboot = ironic.drivers.pxe:PXEAndIBootDriver
pxe_ilo = ironic.drivers.pxe:PXEAndIloDriver
pxe_drac = ironic.drivers.drac:PXEDracDriver
pxe_snmp = ironic.drivers.pxe:PXEAndSNMPDriver
pxe_irmc = ironic.drivers.pxe:PXEAndIRMCDriver
pxe_amt = ironic.drivers.pxe:PXEAndAMTDriver
pxe_msftocs = ironic.drivers.pxe:PXEAndMSFTOCSDriver
pxe_ucs = ironic.drivers.pxe:PXEAndUcsDriver
pxe_wol = ironic.drivers.pxe:PXEAndWakeOnLanDriver
pxe_iscsi_cimc = ironic.drivers.pxe:PXEAndCIMCDriver
pxe_agent_cimc = ironic.drivers.agent:AgentAndCIMCDriver
#fake* 驱动是假的驱动,里面没有具体实现,用于测试
fake = ironic.drivers.fake:FakeDriver
fake_agent = ironic.drivers.fake:FakeAgentDriver
fake_inspector = ironic.drivers.fake:FakeIPMIToolInspectorDriver
fake_ipmitool = ironic.drivers.fake:FakeIPMIToolDriver
fake_ipminative = ironic.drivers.fake:FakeIPMINativeDriver
fake_ssh = ironic.drivers.fake:FakeSSHDriver
fake_pxe = ironic.drivers.fake:FakePXEDriver
fake_seamicro = ironic.drivers.fake:FakeSeaMicroDriver
fake_iboot = ironic.drivers.fake:FakeIBootDriver
fake_ilo = ironic.drivers.fake:FakeIloDriver
fake_drac = ironic.drivers.fake:FakeDracDriver
fake_snmp = ironic.drivers.fake:FakeSNMPDriver
fake_irmc = ironic.drivers.fake:FakeIRMCDriver
fake_vbox = ironic.drivers.fake:FakeVirtualBoxDriver
fake_amt = ironic.drivers.fake:FakeAMTDriver
fake_msftocs = ironic.drivers.fake:FakeMSFTOCSDriver
fake_ucs = ironic.drivers.fake:FakeUcsDriver
fake_cimc = ironic.drivers.fake:FakeCIMCDriver
fake_wol = ironic.drivers.fake:FakeWakeOnLanDriver
可以将上面的驱动进行分类,得到:
- pxe/iscis
- agent
- fake (假的驱动,用于示例,测试)
我们把fake驱动排除,其他的驱动可以分为两类:
- 一是以pex 或者 iscsi 为前缀的驱动采用PXE部署机制,这些驱动将根硬盘作为iSCSI设备暴露给ironic conductor,由conductor将镜像复制到这里.
- 二是以agent_ 为前缀的驱动采用Agent部署机制,conductor准备一个存储在swift上的镜像URL给IPA,由IPA下载镜像和完成部署的操作。
从Kilo版开始,所有驱动使用agent进行部署。
每种驱动的功能会调用不同的模块来实现,比如:
- pxe_ deploy 用的是iscsi_deploy.ISCSIDeploy(), boot用的是pxe.PXEBoot(), power根据后缀不同使用的不同
- agent_ deploy用的是agent.AgentDeploy(), boot 用的是pxe.PXEBoot(), power根据后缀不同而不同
- iscis_ deploy用的iscsi_deploy.ISCSIDeploy(),power根据后缀不同而不同
驱动列表
- 社区驱动
种类 | 用途 | 实现的驱动 |
---|---|---|
SSH | 用VM模拟物理机时使用 | pxe-ssh使用pxe部署、ssh管理电源; agent-ssh使用agent部署、ssh管理电源 |
VirtualBox | VirtualBox驱动用来将虚拟机模拟成裸机节点进行测试Ironic。Ironic使用pex_ssh和agent_ssh驱动连接VirtualBox主机(要安装在Linux下,Windows下SSH不太好用) | - pxe_vbox:使用基于iSCSI的部署机制- agent_vbox:使用基于agent的部署机制 |
IPMI | 使用IPMItool进行管理电源 | pxe_ipmitool; agent_ipmitool; |
pyghmi | pyghmi是ironic实现的一个Python ipmitool lib 用于替代ipmitool | pxe_ipminative;agent_pyghmi |
- 厂商驱动
种类 | 说明 | 实现的驱动 |
---|---|---|
DRAC | 戴尔公司的一种系统管理硬件和软件解决方案(Dell Remote Access Controller) | pxe_drac |
AMT | 英特尔主动管理技术,远程带外管理个人电脑的硬件和固件的技术,用于监控、维修、更新、升级硬件和固件 | pex_amt |
SNMP | SNMP电源驱动用户管理数据中心机架的配电单元,可与PXE驱动结合起来用于网络部署和配置 | pxe_snmp |
iLO | iLO是Integrated Ligths-out的简称,是HP服务器上集成的远程管理端口,只要将服务器接入网络并且没有断开服务器的电源,不管HP服务器的处于何种状态(开机、关机、重启),都可以允许用户通过网络进行远程管理 | iscsi_ilo, agent_ilo, pxe_ilo。 iscsi_ilo和agent_ilo使用iLO实现带外管理,iscsi_ilo使用diskimage-builder建立镜像,从网络启动;而agent_ilo使用IPA的部署镜像,裸机节点从本地启动。pxe_ilo使用PXE/iSCSI部署(和常规PXE驱动一样) |
SeaMicro | SeaMicro服务器是由AMD公司发布的,基于ARM处理器,特点是节能。SeaMicro电源驱动可以使用SeaMicro服务器的电源周期管理功能。 | pxe_seamicro, 使用PXE/iSCSI进行部署镜像,然后使用SeaMicro替代IPMI对裸机进行管理。 |
iRMC | 富士通的驱动,通过ServerView Common Command Interface(SCCI,富士通的卡)控制电源 | - pxe_irmc,使用PXE部署 - iscis_irmc,支持用虚拟光驱来部署镜像 - agent_irmc,支持使用虚拟光驱部署IPA |
UCS | 思科的驱动,用户管理思科 UCS B/C 系列的服务器(类似IPMI) | - pxe_ucs: 使用PXE/iSCSI部署镜像,使用UCS代替IPMI管理节点 - agent_ucs:使用IPAramdisk部署镜像,使用UCS代替IPMI管理节点 |
CIMC | 思科为standalone Cisco UCS C系列服务器提供的驱动,可以利用CIMC进行管理裸机(代替IPMI) | pxe_iscsi_cimc,使用PXE+iSCSI部署 - pxe_agent_cimc,使用PXE启动+Agent部署 |
Wake-On-Lan | Wake-On-Lan是一个允许通过网络消息打开电脑电源的标准,不需要额外硬件,但还在测试阶段。Wake-On-Lan只有打开电源的功能,关闭电源需要手工执行。它没有获取电源状态的能力,任何电源状态的API调用它只返回数据库里的值。 | pex_wol:使用PXE/iPXE启动,iSCSI部署。 |
iBoot | iBoot power driver通过DxP协议对使用了Dataprobe(美国一家制造商)iBoot 设备的服务器进行电源周期管理 | pxe_iboot,使用PXE/iPXE启动,iSCSI部署。 |
Ironic-Python-Agent
在PXE部署环境中,deploy模块是通过打开一个iSCSI设备,ironic-conductro将OS的镜像文件写到iSCSI的设备,所以deploy_ramdisk只是完成了iSCSI部署的工作,但开发者觉得既然已经把kernel和ramdisk传过去了,只做一个工作是不是太少了,而且还太缺乏灵活性了,所以就想在ramdisk里装一个Python Agent。 实际上就是多提供了一个Restful API,控制节点可以通过这个agent远程实现与物理机节点互动,而不仅仅使用dd命令。
Ironic Python Agent(简称IPA或者agent)是一个基于python的代理,用于处理ironic中裸机节点的一系列动作,比如检查、配置、清除和部署镜像。运行在ramdisk中,暴露出REST API给conductor。Ironic-Python-Agent可以在deploy模块直接访问硬件,提供以下功能:
- 磁盘格式化
- 磁盘分区
- 安装OS( Bootloaders, OS)
- 固件升级
- raid配置
在Condutor端使用agent驱动,物理机端使用IPA,IPA通过暴露API给Condutor调用,则可完成相应功能。IPA启动时通过发送lookup()请求给Condutor获取UUID,相当于注册自己,并且每隔一段时间给Condutor发送心跳包进行连接。
1. 与conductor的交互
IPA使用lookup和hearteat机制与Ironic Conductor进行交互
- 启动时agent给Conductor的vendor_passthru lookup endpoint(地址为/v1/drivers/{driver}/vendor_passthru/lookup)发送一个硬件的profile
- 然后Ironic就可以得出该节点的uuid,在成功发现该节点之后,agent隔N秒发送心跳包给Conductor(hearteat地址为/v1/nodes/{node_ident}/vendor_passthru/heartbeat )
- conductor执行一系列动作,包括查询已经运行的命令的状态,
2. 与ramdisk、agent的关系
IPA是一个运行在ramdisk中python程序,当物理机注册时使用agent为前缀的驱动时,则会使用agent方式部署,即允许包含有IPA的ramdisk。
3. 硬件管理
硬件管理器(HardwareManager)是IPA中的一个概念,IPA通过重写硬件管理器来支持多种硬件平台。通过自定义 hardware managers 可以允许用户引入特定的硬件工具集、文件和清除步骤等等,比如可以引入 BIOS flashing utility and BIOS file,然后在cleaning step中重写BIOS版本。
修改硬件的方法按照优先顺序发送给每个管理器,管理器检查是否包含该方法,如果没有则抛出IncompatibleHardwareMethodError异常,IPA继续发送给下一个管理器,直到某个管理器包含该方法并且返回方法的结果,如果所有的管理器都没有改方法则抛出 HardwareManagerMethodNotFound异常。
4. pxe部署与agent部署对比
使用pxe部署流程:
使用IPA部署流程:
剖析ironic的更多相关文章
- 探索C#之6.0语法糖剖析
阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...
- jQuery之Deferred源码剖析
一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...
- [C#] 剖析 AssemblyInfo.cs - 了解常用的特性 Attribute
剖析 AssemblyInfo.cs - 了解常用的特性 Attribute [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5944391.html 序 ...
- Membership三步曲之进阶篇 - 深入剖析Provider Model
Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...
- 《AngularJS深度剖析与最佳实践》简介
由于年末将至,前阵子一直忙于工作的事务,不得已暂停了微信订阅号的更新,我将会在后续的时间里尽快的继续为大家推送更多的博文.毕竟一个人的力量微薄,精力有限,希望大家能理解,仍然能一如既往的关注和支持sh ...
- 探索c#之Async、Await剖析
阅读目录: 基本介绍 基本原理剖析 内部实现剖析 重点注意的地方 总结 基本介绍 Async.Await是net4.x新增的异步编程方式,其目的是为了简化异步程序编写,和之前APM方式简单对比如下. ...
- ASP.NET Core管道深度剖析(2):创建一个“迷你版”的管道来模拟真实管道请求处理流程
从<ASP.NET Core管道深度剖析(1):采用管道处理HTTP请求>我们知道ASP.NET Core请求处理管道由一个服务器和一组有序的中间件组成,所以从总体设计来讲是非常简单的,但 ...
- [C#] 走进异步编程的世界 - 剖析异步方法(上)
走进异步编程的世界 - 剖析异步方法(上) 序 这是上篇<走进异步编程的世界 - 开始接触 async/await 异步编程>(入门)的第二章内容,主要是与大家共同深入探讨下异步方法. 本 ...
- [C#] 走进异步编程的世界 - 剖析异步方法(下)
走进异步编程的世界 - 剖析异步方法(下) 序 感谢大家的支持,这是昨天发布<走进异步编程的世界 - 剖析异步方法(上)>的补充篇. 目录 异常处理 在调用方法中同步等待任务 在异步方法中 ...
随机推荐
- webapi + windows计划 + mshta 实现定时执行任务
当然,实现定时任务有更好的操作方式,比如方式一:asp.net mvc+quartz.net +corn +webapi,asp.net mvc做任务管理的平台,使用CronTrigger做定时触发, ...
- 【CodeForces】901 C. Bipartite Segments
[题目]C. Bipartite Segments [题意]给定n个点m条边的无向连通图,保证不存在偶数长度的简单环.每次询问区间[l,r]中包含多少子区间[x,y]满足只保留[x,y]之间的点和边构 ...
- 【CodeForces】899 E. Segments Removal
[题目]E. Segments Removal [题意]给定n个数字,每次操作删除最长的连续相同数字(等长删最左),求全部删完的最少次数.n<=2*10^6,1<=ai<=10^9. ...
- NYOJ 141 Squares (数学)
题目链接 描述 A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degre ...
- Test plan
Options for Test Strategy: 1. Regular test: all the planned test cases will be executed 2. Extented ...
- 记一次powershell反混淆(2)
样本地址 https://www.hybrid-analysis.com/sample/4b4b8b13c264c8f7d7034060e0e4818a573bebc576a94d7b13b4c174 ...
- 64_o1
OCE-devel-0.18.1-1.fc26.i686.rpm 15-May-2017 18:37 5634474 OCE-devel-0.18.1-1.fc26.x86_64.rpm 15-May ...
- keepalived主备切换后的arp问题【转】
使用keepalived的时候主机挂了,备机显示绑定了VIP.但是此时实际还是不能访问.其实就是网关的arp缓存没有刷新. 在服务器上执行一下就行了 arping -I eth0 -c 5 -s ...
- 微信access_token和refresh_token保存于redis
简介 通常理解的access_token和refresh_token access_token是用来对客户端进行认证的,类似与密码,有一定的有效期.当过期后可使用refresh_token重新获取一个 ...
- Hashtable之Properties
properties的使用:1.Hashtable的实现类,线程安全.与HashMap不同,Hashtable不允许使用null作为key和value2.和HashMap一样,Hashtable也不能 ...