Haproxy 透传IP配置方法及测试

news/2024/5/10 21:40:51/文章来源:https://blog.csdn.net/lizongti/article/details/117223286

Haproxy 透传IP配置方法

  • 1. 环境准备
  • 2. 测试准备
    • 2.1 启动Haproxy容器方法
      • 2.1.1 拉取官方haproxy镜像
      • 2.1.2 删除旧的容器
      • 2.1.3 编写haproxy配置
      • 2.1.4 运行配置检查
      • 2.1.5 启动容器
      • 2.1.6 更改配置
    • 2.2 Golang Server编写
      • 2.2.1 TCP Server
      • 2.2.2 HTTP Server
    • 2.3 客户端测试
      • 2.3.1 设置网络
      • 2.3.3 添加hosts(模拟DNS)
  • 3. haproxy 参数解释
    • 3.2 send-proxy
    • 3.3 source 0.0.0.0 usesrc clientip
  • 4. 测试
    • 4.1 TCP无透传参数
      • 4.1.1 测试过程
      • 4.1.2 结论
    • 4.2 HTTP 无透传参数
      • 4.2.1 测试过程
      • 4.2.2 结论
    • 4.3 TCP使用send_proxy参数
      • 4.3.1 测试过程
      • 4.3.2 结论
    • 4.4 HTTP使用forward for参数
      • 4.4.1 测试过程
      • 4.4.2 结论

1. 环境准备

  • golang 运行环境
  • docker 运行环境
  • vmware 虚拟机(centos7 x64)

2. 测试准备

2.1 启动Haproxy容器方法

2.1.1 拉取官方haproxy镜像

docker pull haproxy:latest

2.1.2 删除旧的容器

如果存在旧的容器,需要停止和删除

docker stop haproxy && docker rm haproxy

2.1.3 编写haproxy配置

新建一个工作目录,在工作目录种新建haproxy.cfg,添加以下内容

global
daemon
ulimit-n 1048576defaults
mode tcp
retries 3
option redispatch
option abortonclose
option dontlognull
maxconn 100000timeout server 60m
timeout connect 5s
timeout client 60m
timeout http-request 1m
timeout queue 5s
timeout http-keep-alive 1m
timeout check 1m#############################
# Add listener config below #
#############################
listen httpbind *:80mode httpmaxconn 20000server s1 172.169.18.20:20000

2.1.4 运行配置检查

进入工作目录后
Shell或者Git Bash下使用:

docker run -it --rm --name haproxy-syntax-check \-v `pwd`:/usr/local/etc/haproxy:ro \
haproxy:latest -c -f /usr/local/etc/haproxy/haproxy.cfg

CMD或者PS下使用

docker run -it --rm --name haproxy-syntax-check ^-v %cd%:/usr/local/etc/haproxy:ro ^
haproxy:latest -c -f /usr/local/etc/haproxy/haproxy.cfg

显示

Configuration file is valid

2.1.5 启动容器

进入工作目录后
Shell或者Git Bash下使用:

docker run -d \--name haproxy \--hostname haproxy \--sysctl net.ipv4.ip_forward=1 \--sysctl net.ipv4.tcp_timestamps=0 \--sysctl net.ipv4.ip_unprivileged_port_start=0 \--restart=always \--privileged=true \--log-opt max-size=10m \--log-opt max-file=10 \--ulimit nofile=1048576:1048576 \-v /etc/localtime:/etc/localtime:ro \-v /etc/timezone:/etc/timezone:ro \-v `pwd`:/usr/local/etc/haproxy:ro \-p 80:80 \
haproxy:latest

CMD或者PS下使用:

docker run -d ^--name haproxy ^--hostname haproxy ^--sysctl net.ipv4.ip_forward=1 ^--sysctl net.ipv4.tcp_timestamps=0 ^--sysctl net.ipv4.ip_unprivileged_port_start=0 ^--restart=always ^--privileged=true ^--log-opt max-size=10m ^--log-opt max-file=10 ^--ulimit nofile=1048576:1048576 ^-v /etc/localtime:/etc/localtime:ro ^-v /etc/timezone:/etc/timezone:ro ^-v %cd%:/usr/local/etc/haproxy:ro ^-p 80:80 ^
haproxy:latest

显示

4b1e3cb0afa5ed1c2385944ce439794df4e70c2fb04d365113c22358770c5707

启动成功

2.1.6 更改配置

更改配置后使用如下命令重载配置

docker kill -s HUP haproxy

注意不要更改暴露端口,否则要重新配置haproxy容器端口参数

2.2 Golang Server编写

2.2.1 TCP Server

使用Golang实现简单的TCP服务器 tcp.go

package mainimport ("log""net"
)func main() {listener, err := net.Listen("tcp", ":20000")if err != nil {log.Fatalln(err.Error())}defer listener.Close()for {conn, err := listener.Accept()if err != nil {log.Println(err.Error())continue}go func(conn net.Conn) {defer func() {if err := conn.Close(); err != nil {log.Println(err.Error())}}()log.Printf("local addr: %s, remote addr: %s", conn.LocalAddr(), conn.RemoteAddr())}(conn)}
}

启动TCP服务器

go run tcp.go 

2.2.2 HTTP Server

使用Golang实现简单的TCP服务器 http.go

package mainimport ("log""net/http"
)func main() {http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {log.Printf("request uri: %s, proto: %s, host: %s, user agent: %s, remote addr: %s, x-forwarded-for: %s",r.URL.RequestURI(), r.Proto, r.Host, r.UserAgent(), r.RemoteAddr, r.Header.Get("X-Forwarded-For"))w.Write([]byte("OK\n"))})err := http.ListenAndServe(":20020", nil)if err != nil {log.Fatalln(err.Error())}
}

启动HTTP服务器

go run http.go 

2.3 客户端测试

2.3.1 设置网络

Vmware 虚拟机安装CentOS镜像
按照如下方式设置桥接模式,复制物理网络的连接状态
在这里插入图片描述
查询IP

[tony@localhost ~]$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0ether 02:42:dc:69:8a:b1  txqueuelen 0  (Ethernet)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 172.169.18.174  netmask 255.255.255.0  broadcast 172.169.18.255inet6 fe80::babe:c69c:22a5:6d14  prefixlen 64  scopeid 0x20<link>ether 00:0c:29:23:21:a3  txqueuelen 1000  (Ethernet)RX packets 757  bytes 91426 (89.2 KiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 94  bytes 11675 (11.4 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0inet6 ::1  prefixlen 128  scopeid 0x10<host>loop  txqueuelen 1000  (Local Loopback)RX packets 68  bytes 5916 (5.7 KiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 68  bytes 5916 (5.7 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255ether 52:54:00:95:71:3a  txqueuelen 1000  (Ethernet)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

虚拟机IP为172.169.18.174
本机IP为172.169.18.20

2.3.3 添加hosts(模拟DNS)

在CentOS虚拟机上添加hosts
echo “remote addr: 172.169.18.20:57402” >> /etc/hosts

3. haproxy 参数解释

https://gist.github.com/PiBa-NL/d826e0d6b35bbe4a5fc3

To send the ip addres of the client/webbrowser to the server/webserver behind it there are a few options:1- option forwardfor2- send-proxy3- source 0.0.0.0 usesrc clientip1- option forwardfor
This is an easy option to configure in haproxy, it does require that http layer7 processing is used 'mode http' and the webserver/ webapplication that wants to log or use the ip of the client must use the http-header 'X-Forwarded-For' to read the clientip.

3.2 send-proxy

  • 包含send-proxy(send-proxy-v1), send-proxy-v2, send-proxy-*(其他版本) 等版本
  • TCP和HTTP均可用,但是要求服务端升级ProxyProtocol。Golang下可以使用https://github.com/pires/go-proxyproto, 其他语言也有对应的库。
  • ProxyProtocol本质是变种TCP。有些应用是通过在TCP协议前面增加IP信息来支持ProxyProtocol,send-proxy协议增加的IP信息为字符串,send-proxy-v2增加的IP信息为字节,性能更优。

3.3 source 0.0.0.0 usesrc clientip

This allows any application and any protocol to be used and see the actual client ip as the origin from the incomming connection.
It does however require to configure IPTABLES or IPFW or other firewall rules to capture reply-traffic, also the haproxy machine must be the defaultroute for the return traffic from the (web-)server.
@LeonanCarvalho

iptables 范例

#!/bin/bash
iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 111
iptables -t mangle -A DIVERT -j ACCEPT
ip rule add fwmark 111 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

http://cbonte.github.io/haproxy-dconv/2.5/configuration.html#2
source [:] [usesrc { [:] | client | clientip } ]
source [:] [usesrc { [:] | hdr_ip([,]) } ]
source [:] [interface ]
Set the source address for outgoing connections
May be used in sections :

defaults frontend listen backend
yes
yes no
no yes
yes yes
yes
Arguments :
is the IPv4 address HAProxy will bind to before connecting to a
server. This address is also used as a source for health checks.

      The default value of 0.0.0.0 means that the system will selectthe most appropriate address to reach its destination. Optionallyan address family prefix may be used before the address to forcethe family regardless of the address format, which can be usefulto specify a path to a unix socket with no slash ('/'). Currentlysupported prefixes are :- 'ipv4@' -> address is always IPv4- 'ipv6@' -> address is always IPv6- 'unix@' -> address is a path to a local unix socket- 'abns@' -> address is in abstract namespace (Linux only)You may want to reference some environment variables in theaddress parameter, see section 2.3 about environment variables.

is an optional port. It is normally not needed but may be useful
in some very specific contexts. The default value of zero means
the system will select a free port. Note that port ranges are not
supported in the backend. If you want to force port ranges, you
have to specify them on each “server” line.

is the IP address to present to the server when connections are
forwarded in full transparent proxy mode. This is currently only
supported on some patched Linux kernels. When this address is
specified, clients connecting to the server will be presented
with this address, while health checks will still use the address
.

is the optional port to present to the server when connections
are forwarded in full transparent proxy mode (see above).
The default value of zero means the system will select a free
port.

is the name of a HTTP header in which to fetch the IP to bind to.
This is the name of a comma-separated header list which can
contain multiple IP addresses. By default, the last occurrence is
used. This is designed to work with the X-Forwarded-For header
and to automatically bind to the client’s IP address as seen
by previous proxy, typically Stunnel. In order to use another
occurrence from the last one, please see the parameter
below. When the header (or occurrence) is not found, no binding
is performed so that the proxy’s default IP address is used. Also
keep in mind that the header name is case insensitive, as for any
HTTP header.

is the occurrence number of a value to be used in a multi-value
header. This is to be used in conjunction with “hdr_ip()”,
in order to specify which occurrence to use for the source IP
address. Positive values indicate a position from the first
occurrence, 1 being the first one. Negative values indicate
positions relative to the last one, -1 being the last one. This
is helpful for situations where an X-Forwarded-For header is set
at the entry point of an infrastructure and must be used several
proxy layers away. When this value is not specified, -1 is
assumed. Passing a zero here disables the feature.

is an optional interface name to which to bind to for outgoing
traffic. On systems supporting this features (currently, only
Linux), this allows one to bind all traffic to the server to
this interface even if it is not the one the system would select
based on routing tables. This should be used with extreme care.
Note that using this option requires root privileges.
The “source” keyword is useful in complex environments where a specific
address only is allowed to connect to the servers. It may be needed when a
private address must be used through a public gateway for instance, and it is
known that the system cannot determine the adequate source address by itself.

An extension which is available on certain patched Linux kernels may be used
through the “usesrc” optional keyword. It makes it possible to connect to the
servers with an IP address which does not belong to the system itself. This
is called “full transparent proxy mode”. For this to work, the destination
servers have to route their traffic back to this address through the machine
running HAProxy, and IP forwarding must generally be enabled on this machine.

In this “full transparent proxy” mode, it is possible to force a specific IP
address to be presented to the servers. This is not much used in fact. A more
common use is to tell HAProxy to present the client’s IP address. For this,
there are two methods :

  • present the client’s IP and port addresses. This is the most transparent
    mode, but it can cause problems when IP connection tracking is enabled on
    the machine, because a same connection may be seen twice with different
    states. However, this solution presents the huge advantage of not
    limiting the system to the 64k outgoing address+port couples, because all
    of the client ranges may be used.

  • present only the client’s IP address and select a spare port. This
    solution is still quite elegant but slightly less transparent (downstream
    firewalls logs will not match upstream’s). It also presents the downside
    of limiting the number of concurrent connections to the usual 64k ports.
    However, since the upstream and downstream ports are different, local IP
    connection tracking on the machine will not be upset by the reuse of the
    same session.

This option sets the default source for all servers in the backend. It may
also be specified in a “defaults” section. Finer source address specification
is possible at the server level using the “source” server option. Refer to
section 5 for more information.

In order to work, “usesrc” requires root privileges.
Examples :
backend private
# Connect to the servers using our 192.168.1.200 source address
source 192.168.1.200

backend transparent_ssl1
# Connect to the SSL farm from the client’s source address
source 192.168.1.200 usesrc clientip

backend transparent_ssl2
# Connect to the SSL farm from the client’s source address and port
# not recommended if IP conntrack is present on the local machine.
source 192.168.1.200 usesrc client

backend transparent_ssl3
# Connect to the SSL farm from the client’s source address. It
# is more conntrack-friendly.
source 192.168.1.200 usesrc clientip

backend transparent_smtp
# Connect to the SMTP farm from the client’s source address/port
# with Tproxy version 4.
source 0.0.0.0 usesrc clientip

backend transparent_http
# Connect to the servers using the client’s IP as seen by previous
# proxy.
source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)

4. 测试

4.1 TCP无透传参数

4.1.1 测试过程

  • 更改haproxy配置
listen tcpbind *:80mode tcpmaxconn 20000server h1 172.169.18.20:20000 send_proxy

重载配置,启动server进程

docker kill -s HUP haproxy
go run tcp.go
  • 执行虚拟机curl测试
 curl server
  • golang日志
2021/05/24 15:56:11 local addr: 172.169.18.20:20000, remote addr: 172.169.18.20:57402

4.1.2 结论

现象: remote addr: 172.169.18.20:57402 显示的是本机地址,并非真正的远程地址
结论: 默认情况下无法透传TCP的远程地址

4.2 HTTP 无透传参数

4.2.1 测试过程

  • 更改haproxy配置
listen httpbind *:80mode httpmaxconn 20000server s1 172.169.18.20:20000

重载配置,启动server进程

docker kill -s HUP haproxy
go run http.go
  • 执行虚拟机curl测试
 curl server
  • golang日志
2021/05/24 18:22:07 request uri: /, proto: HTTP/1.1, host: server1, user agent: curl/7.29.0, remote 
addr: 172.169.18.20:63547, x-forwarded-for:

4.2.2 结论

  • 现象: x-forwarded-for 为空

  • 结论: 默认情况下无法透传HTTP的远程地址

4.3 TCP使用send_proxy参数

4.3.1 测试过程

  • 更改并重载haproxy配置
listen tcpbind *:80mode tcpmaxconn 20000server h1 172.169.18.20:20000 send-proxy

重载配置,启动server进程

docker kill -s HUP haproxy
go run tcp.go
  • 执行虚拟机curl请求
 curl server 
  • Go日志
2021/05/24 15:56:11 local addr: 172.169.18.20:20000, remote addr: 172.169.18.20:57402

4.3.2 结论

4.4 HTTP使用forward for参数

4.4.1 测试过程

  • 更改并重载haproxy配置
listen httpbind *:80mode httpoption forwardformaxconn 20000server s1 172.169.18.20:20000

重载配置,启动server进程

docker kill -s HUP haproxy
go run http.go
  • 执行虚拟机curl请求
 curl server
  • Go日志
2021/05/24 18:57:09 request uri: /, proto: HTTP/1.1, host: server, user agent: curl/7.29.0, remote addr: 172.169.18.20:64634, x-forwarded-for: 172.17.0.1

4.4.2 结论

  • 现象: x-forwarded-for 显示出的远端地址(在外网情况下,会显示成外网IP)

  • 结论: 使用forwardfor可以通过x-forwad-for Header透传HTTP的远程地址,远程地址不受影响

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于VC++运行库报错

Microsoft Visual C&#xff08;简称Visual C、MSVC、VC或VC&#xff09;是微软公司的C开发工具&#xff0c;具有一体化开发环境&#xff0c;可提供编辑 C语言&#xff0c;C以及C/CLI等程式语言。 VC集成了便利的调试工具&#xff0c;特别是整合了微软Windows窗口操作系统应用程…

家用网络常识

目前家庭使用的网速一般 运营商 销售的宽带,会说 50M 100M 200M 300M 这个 100M 指的就是 100M bit/s,而我们都知道 8bit相当于一个字节,也就是1B,所以换算成字节,其实是 12.5M B/s,也就是12.5M,12.5兆换算关系 1 KB = 1024 B 1 MB = 1024 KB 1 GB = 1024 MB 1 TB = 102…

联邦学习开源框架方案选型

无知者&#xff1a;【联邦学习开源框架】FedLab - 加速FL算法验证 联邦学习开源框架FedLab相关 FATE 单位&#xff1a;微众银行 github: https://github.com/FederatedAI/FATE star&#xff1a;3.2k docs&#xff1a;https://github.com/FederatedAI/FATE/blob/master/doc…

电力系统中新型预测双二元变量机组组合问题(Matlab代码实现)

目录 1 概述 2 Matlab代码实现 3 参考文献 1 概述 高效求解大规模 SCUC 问题的关键在于削减其规模。文献[1]表明&#xff0c;安全约束机组组合问题中 大量的故障态安全约束是冗余且无效的&#xff0c;不会对SCUC 问题的最优解产生影响。因此&#xff0c;可以通过辨 识、删除…

为什么ArrayList的subList结果不能转换为ArrayList????

subList是List接口中的一个方法,该方法主要返回一个集合中的一段子集,可以理解为截取一个集合中的部分元素,它的返回值也是一个List。 让我们初始化一个例子:import java.util.ArrayList; import java.util.List;public class SubList_demo {public static void main(Strin…

OPTEE:CA-TA会话的创建(二)

前言 在上一篇我们知道TA是什么&#xff0c;以及为什么需要加载TA。这里来写写加载TA后&#xff0c;怎么CA和TA&#xff0c;TA和TA怎么建立会话&#xff0c;实现我们的功能的。 参考内容全部来自《手机安全和可信应用开发指南》&#xff0c;少有OPTEE书籍&#xff0c;感恩前辈…

牛客网-SQL专项训练15

①MySQL是一种(关系型)数据库管理系统。 关系型数据库的代表包括Oracle, Sql Server, MySQL。 ②小李在创建完一张数据表后,发现少创建了一列,此时需要修改表结构,应该用哪个语句进行操作?C 解析: 题目中说了需要修改表的结构, 故需要使用alter table 添加列: ALTER T…

大数据技术分享 - 话题挑战跳大开团

CSDN话题挑战赛第2期 参赛话题&#xff1a;大数据技术分享 大数据技术分享 - 话题挑战跳大开团 文章目录大数据技术分享 - 话题挑战跳大开团一、披挂上阵【老将出马】1. 历史战绩2. 再战江湖二、先手跳大【勇于开团】1. 个人经历2. Buff自取三、兵精粮足【底蕴深厚】1. 写作模…

QT串口助手-ZUA课设

QT串口助手成品展示QT全部程序构成zua.proserial.hmain.cppserial.cppserial.uiKeil全部程序构成main.cstm32f10x_conf.hstm32f10x_it.c5.stm32f10x_it.hbsp_usart.cbsp_led.cbsp_exit.cbsp_dht11.cbsp_delay.c介绍硬件野火F103指南者DHT11温湿度传感器QT全部程序构成QT设计的思…

虚拟机中centos扩展根目录空间

文章目录一、在vmware上为centos扩展存储二、在centos上扩充在进行yum安装软件时&#xff0c;由于空间不足一直提示“文件系统根目录上从磁盘空间不足”一、在vmware上为centos扩展存储 二、在centos上扩充 运行 df -h 查看容量情况&#xff0c;发现新扩展的空间并没有加载上。…

Babel 插件:30分钟从入门到实战

动手点关注 干货不迷路 &#x1f447;Babel 是一个 source to source&#xff08;源码到源码&#xff09;的 JavaScript 编译器&#xff0c;简单来说&#xff0c;你为 Babel 提供一些 JavaScript 代码&#xff0c;Babel 可以更改这些代码&#xff0c;然后返回给你新生成的代码。…

LeetCode程序员面试金典(第 6 版)上

目录 面试题 01.01. 判定字符是否唯一 面试题 01.03. URL化 面试题 01.04. 回文排列 面试题 01.05. 一次编辑 面试题 01.06. 字符串压缩 面试题 01.07. 旋转矩阵 面试题 01.08. 零矩阵 面试题 01.09. 字符串轮转 面试题 02.01. 移除重复节点 面试题 02.02. 返回倒数第…

BI测试

关于BI测试 前言:由于之前做过一段时间大数据测试,故整理BI测试知识点以供学习。BI测试: BI是从数据接入、数据准备、数据分析、数据可视化到数bai据分发应用的一系列过程,目的是为了辅助企业高效决策。而报表虽然最终也实现了数据可视化,但是对于数据分析的维度、深度、颗…

【数据结构与算法】排序(下篇)

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《数据结构与算法》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 排序⚽归并排序⚾递归实现⚾非递归实现⚽常见排序算法的复杂度和稳定性分析⚾稳定性⚾具体分…

docker安装mysql(单体)

docker安装mysql mac的m1芯片上不支持5.7版本的镜像&#xff0c;因此可以直接选择拉取8.0及之后的版本 docker pull mysql创建mysql的宿主机数据卷挂载的文件夹 # mysql的配置文件&#xff0c;注意conf.d文件夹必须要创建&#xff0c;否则启动容器的时候&#xff0c;数据卷 …

linux 锁-- atomic per_cpu

atomic引入背景 对于 SMP 系统中&#xff0c;在开启 preempt 情况下&#xff0c;对于公共资源&#xff0c;如果存在两个 task 来进行更改&#xff0c;这就面临临界区资源竞争问题&#xff0c;此时会产生意想不到的结果&#xff0c;这是不符合预期的&#xff0c;因此需要来进行…

nginx-nginx的文件服务器的配置

nginx的文件服务器的配置location /data {charset gbk,utf-8;autoindex on;autoindex_exact_size off;autoindex_localtime on;limit_rate_after 10m;alias D:;allow all; }访问文件路径xxx/data访问成功的返回界面

CAS:385437-57-0,DSPE-PEG-Biotin,Biotin-PEG-DSPE,磷脂-聚乙二醇-生物素试剂供应

DSPE-PEG-Biotin&#xff08;磷脂-聚乙二醇-生物素&#xff09;的分子量有&#xff1a;1k&#xff0c;2k&#xff0c;3.4k等&#xff0c;其它的分子量可以定制。质量控制在95%&#xff0c;Biotin-PEG-DSPE主要用于科研实验使用&#xff0c;非药用&#xff0c;非食用。它溶于水和…

ETH 2.0 背景下的新机会与新叙事

以太坊 POW 到 POS 的转型为整个 Web3 行业的发展引入了一层新的叙事&#xff0c;即对于去中心化更深切的要求。TIPS 在 Merge - Shanghai Upgrade 的约 9 个月的小周期内&#xff0c;流通状态的 ETH 在持续单调递减&#xff1b; 从长远来看&#xff0c;未来 ETC 等 Ethhash P…

多人协作多版本开发冲突的正确解决姿势

多人版本开发工作流程&#xff1a;https://blog.csdn.net/qq_32442973/article/details/125717959 这里实际上用上一个关键命令&#xff1a;git merge --no-ff 分支名 注意&#xff1a;无论何种情况&#xff0c;都绝不允许把开发、测试、预生产的代码拉到自己分支上解决冲突&am…