精华内容
下载资源
问答
  • proxy
    千次阅读
    2021-05-28 16:34:55

    目录

    1. 关于缓冲区指令

    1.1 proxy_buffer_size

     
    1. 语法: proxy_buffer_size size;

    2. 默认值: proxy_buffer_size 4k|8k;

    3. 上下文: http, server, location

    1. 该缓冲用于来自上游服务器响应的开始部分,在该部分通常包含一个小小的响应头
    2. 该缓冲区大小默认等于proxy_buffers指令设置的一块缓冲区的大小,没有必要也跟着设置太大。 proxy_buffer_size最好单独设置,一般设置个4k就够了,但它也可以被设置得更小。
    3. 一块缓冲区的大小通常等于一个内存页的大小(4K或者8K),获取Linux 内存页(基页)大小的命令:getconf PAGE_SIZE,一般的输出是4096,即 4KB。

    1.2 proxy_buffering

     
    1. 语法: proxy_buffering on | off;

    2. 默认值: proxy_buffering on;

    3. 上下文: http, server, location

    1. 该指令控制缓冲是否启用。默认情况下,它的值是“on”。如果这个设置为off,那么proxy_buffers和proxy_busy_buffers_size这两个指令将会失效。 但是无论proxy_buffering是否开启,对proxy_buffer_size配置都会起作用。
    2. 当开启缓冲时,nginx尽可能快地从被代理的服务器接收响应,再将它存入proxy_buffer_size和proxy_buffers指令设置的缓冲区中。如果响应无法整个纳入内存,那么其中一部分将存入磁盘上的临时文件,某些请求的响应过大,则超过_buffers的部分将被缓冲到硬盘, 当然这将会使读取响应的速度减慢, 影响用户体验。通过proxy_max_temp_file_size和proxy_temp_file_write_size指令可以控制临时文件的写入。
    3. 当关闭缓冲时,收到响应后,nginx立即将其同步传给客户端。nginx不会尝试从被代理的服务器读取整个请求,而是将proxy_buffer_size指令设定的大小作为一次读取的最大长度(所以无论是否开启,proxy_buffer_size都起作用)。每次传输内容小了,效率肯定会有影响。
    4. 响应头“X-Accel-Buffering”传递“yes”或“no”可以动态地开启或关闭代理的缓冲功能。 这个能力可以通过proxy_ignore_headers指令关闭。

    proxy_buffering启用时,要提防使用的代理缓冲区太大。这可能会吃掉你的内存,限制代理能够支持的最大并发连接数。

    1.3 proxy_buffers

     
    1. 语法: proxy_buffers number size;

    2. 默认值: proxy_buffers 8 4k|8k;

    3. 上下文: http, server, location

    1. 为每个连接设置缓冲区的数量为number,每块缓冲区的大小为size。这些缓冲区用于保存从被代理的服务器读取的响应。
    2. proxy_buffers的缓冲区大小一般会设置的比较大,以应付大网页。proxy_buffers当中单个缓冲区的大小是由系统的内存页面大小决定的,Linux系统中一般为4k。 proxy_buffers由缓冲区数量和缓冲区大小组成的。总的大小为number*size。

    1.4 proxy_busy_buffers_size

     
    1. 语法: proxy_busy_buffers_size size;

    2. 默认值: proxy_busy_buffers_size 8k|16k;

    3. 上下文: http, server, location

    1. 当开启缓冲响应的功能以后,在没有读到全部响应的情况下,写缓冲到达一定大小时,nginx一定会向客户端发送响应,直到缓冲小于此值。这条指令用来设置此值。
    2. 同时,剩余的缓冲区可以用于接收响应,如果需要,一部分内容将缓冲到临时文件。该大小默认是proxy_buffer_size和proxy_buffers指令设置单块缓冲大小的两倍。

    1.5 proxy_max_temp_file_size

     
    1. 语法: proxy_max_temp_file_size size;

    2. 默认值: proxy_max_temp_file_size 1024m;

    3. 上下文: http, server, location

    1. 打开响应缓冲以后,如果整个响应不能存放在proxy_buffer_size和proxy_buffers指令设置的缓冲区内,部分响应可以存放在临时文件中。 这条指令可以设置临时文件的最大容量。而每次写入临时文件的数据量则由proxy_temp_file_write_size指令定义。
    2. 写入硬盘的临时文件的大小,如果超过了这个值, Nginx将与Proxy服务器同步的传递内容, 而不再缓冲到硬盘. 设置为0时,将禁止响应写入临时文件,也就相当于直接关闭硬盘缓冲。

    1.6 proxy_temp_file_write_size

     
    1. 语法: proxy_temp_file_write_size size;

    2. 默认值: proxy_temp_file_write_size 8k|16k;

    3. 上下文: http, server, location

    在开启缓冲后端服务器响应到临时文件的功能后,设置nginx每次写数据到临时文件的size(大小)限制。 size的默认值是proxy_buffer_size指令和proxy_buffers指令定义的每块缓冲区大小的两倍, 而临时文件最大容量由proxy_max_temp_file_size指令设置。

    1.7 缓冲区配置实例

    通用网站的配置

     
    1. proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小

    2. proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置

    3. proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)

    4. proxy_temp_file_write_size 64k;

    5. #设定缓存文件夹大小,大于这个值,将从upstream服务器传

    docker registry的配置 这个每次传输至少都是9M以上的内容,缓冲区配置大;

     
    1. proxy_buffering on;

    2. proxy_buffer_size 4k;

    3. proxy_buffers 8 1M;

    4. proxy_busy_buffers_size 2M;

    5. proxy_max_temp_file_size 0;

    关于缓冲区大小的配置,还是需要实地的分析,一般来说通用配置可以应付了。

    2. 常用配置项

    2.1 proxy_cache_path

     
    1. 语法: proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time];

    2. 默认值: —

    3. 上下文: http

    • path 指定缓存文件目录,和 proxy_temp_path 最好设置在同一文件分区下,缓存内容是先写在 temp_path,临时文件和缓存可以放在不同的文件系统,将导致文件在这两个文件系统中进行拷贝,而不是廉价的重命名操作。因此,针对任何路径,都建议将缓存和proxy_temp_path指令设置的临时文件目录放在同一文件系统。
    • level 定义了缓存的层次结构,每层可以用1(最多16中选择,0-f)或2(最多256种选择,00-ff)表示,中间用 [冒号] 分隔。“levels=1:2”表示开启1、2层级(第2层级理论有16*256个目录)。
     
    1. proxy_cache_path /data/nginx/cache; # 所有缓存只有一个目录

    2. /data/nginx/cache/d7b6e5978e3f042f52e875005925e51b

    3.  
    4. proxy_cache_path /data/nginx/cache levels=1:2; # 第二层级有16*256=4096个目录

    5. /data/nginx/cache/b/51/d7b6e5978e3f042f52e875005925e51b

    6.  
    7. proxy_cache_path /data/nginx/cache levels=1:1:1; #第三层级有16*16*16个目录

    8. /data/nginx/cache/b/1/5/d7b6e5978e3f042f52e87500592

    9.  
    10. proxy_cache_path /data/nginx/cache levels=2; # 第一层级有256个目录

    11. /data/nginx/cache/1b/d7b6e5978e3f042f52e875005925e51b

    • keys_zone 指定一个共享内存空间zone,所有活动的键和缓存数据相关的信息都被存放在共享内存中,这样nginx可以快速判断一个request是否命中或者未命中缓存,1m可以存储8000个key,10m可以存储80000个key;
    • inactive inactive=30m 表示 30 分钟没有被访问的文件会被 cache manager 删除,inactive的默认值是10分钟。 需要注意的是,inactive和expired配置项的含义是不同的,expired只是缓存过期,但不会被删除,inactive是删除指定时间内未被访问的缓存文件
    • max_size cache存储的最大尺寸,如果不指定,会用掉所有磁盘空间,当尺寸超过,将会基于LRU算法移除数据,以减少占用大小。nginx启动时,会创建一个“Cache manager”进程,通过“purge”方式移除数据。
    • loader_files “cache loader”进程遍历文件时,每次加载的文件个数。默认为100.
    • loader_threshold 每次遍历消耗时间上限。默认为200毫秒。
    • loader_sleep 一次遍历之后,停顿的时间间隔,默认为50毫秒。

    需要注意的是:

    特殊进程“cache manager”监控缓存的条目数量,如果超过max_size参数设置的最大值,使用LRU算法移除缓存数据。nginx新启动后不就,特殊进程“cache loader”就被启动。该进程将文件系统上保存的过去缓存的数据的相关信息重新加载到共享内存。加载过程分多次迭代完成,每次迭代,进程只加载不多于loader_files参数指定的文件数量(默认值为100)。此外,每次迭代过程的持续时间不能超过loader_threshold参数的值(默认200毫秒)。每次迭代之间,nginx的暂停时间由loader_sleep参数指定(默认50毫秒)。缓存文件并不是越多越好,所以 cache_key 的设计非常关键。代理或 URL 跳转常常会添加的无用请求参数,这就会出现不同的 cache_key 保存了多份相同的缓存内容,这对缓存效果影响很大。

    2.2 proxy_temp_path

     
    1. 语法: proxy_temp_path path [level1 [level2 [level3]]];

    2. 默认值:

    3. proxy_temp_path proxy_temp;

    4. 上下文: http, server, location

    定义从后端服务器接收的临时文件的存放路径,可以为临时文件路径定义至多三层子目录的目录树。 比如,下面配置

    proxy_temp_path /spool/nginx/proxy_temp 1 2;

    那么临时文件的路径看起来会是这样:

    /spool/nginx/proxy_temp/7/45/00000123457

    2.3 proxy_cache

     
    1. 语法: proxy_cache zone | off;

    2. 默认值: proxy_cache off;

    3. 上下文: http, server, location

    指定用于页面缓存的共享内存。同一块共享内存可以在多个地方使用。off参数可以屏蔽从上层配置继承的缓存功能。zone名称由“proxy_cache_path”指令定义。

    2.4 proxy_cache_key

     
    1. 语法: proxy_cache_key string;

    2. 默认值:

    3. proxy_cache_key $scheme$proxy_host$request_uri;

    4. 上下文: http, server, location

    定义如何生成缓存的键,比如

    proxy_cache_key "$host$request_uri $cookie_user";

    这条指令的默认值类似于下面字符串

    proxy_cache_key $scheme$proxy_host$uri$is_args$args;

    缓存文件并不是越多越好,所以 cache_key 的设计非常关键。代理或 URL 跳转常常会添加的无用请求参数,这就会出现不同的 cache_key 保存了多份相同的缓存内容,这对缓存效果影响很大。通过 ngx_lua 可以对 URL 参数进行过滤,保证 cache_key 唯一。

    2.5 proxy_cache_valid

     
    1. 语法: proxy_cache_valid [code ...] time;

    2. 默认值: —

    3. 上下文: http, server, location

    为不同的响应状态码设置不同的缓存时间。比如,下面指令

     
    1. proxy_cache_valid 200 302 10m;

    2. proxy_cache_valid 404 1m;

    设置状态码为200和302的响应的缓存时间为10分钟,状态码为404的响应的缓存时间为1分钟。

    如果仅仅指定了time,

    proxy_cache_valid 5m;

    那么只有状态码为200、300和302的响应会被缓存。

    如果使用了any参数,那么就可以缓存任何响应:

     
    1. proxy_cache_valid 200 302 10m;

    2. proxy_cache_valid 301 1h;

    3. proxy_cache_valid any 1m;

    缓存参数也可以直接在响应头中设定。这种方式的优先级高于使用这条指令设置缓存时间。

     
    1. “X-Accel-Expires”响应头可以以秒为单位设置响应的缓存时间,如果值为0,表示禁止缓存响应,如果值以@开始,表示自1970年1月1日以来的秒数,响应一直会被缓存到这个绝对时间点。

    2. 如果不含“X-Accel-Expires”响应头,缓存参数仍可能被“Expires”或者“Cache-Control”响应头设置。

    3. 如果响应头含有“Set-Cookie”,响应将不能被缓存。 这些头的处理过程可以使用指令proxy_ignore_headers忽略。

    2.6 proxy_ignore_headers

     
    1. 语法: proxy_ignore_headers field ...;

    2. 默认值: —

    3. 上下文: http, server, location

    指定来自后端server的响应中的某些header不会被处理,如下几个fields可以被ignore:“X-Accel-Redirect”、“X-Accel-Expires”、“X-Accel-Limit-Rate”、“X-Accel-Buffering”、“X-Accel-Charset”、“Expires”、“Cache-Control”、“Set-Cookie”、“Vary”。“不被处理”就是nginx不会尝试解析这些header并应用它们,比如nginx处理来自后端server的“Expires”,将会影响它本地的文件cache的机制

    如果不被取消,这些头部的处理可能产生下面结果:

     
    1. “X-Accel-Expires”,“Expires”,“Cache-Control”,和“Set-Cookie” 设置响应缓存的参数;

    2. “X-Accel-Redirect”执行到指定URI的内部跳转;

    3. “X-Accel-Limit-Rate”设置响应到客户端的传输速率限制;

    4. “X-Accel-Buffering”启动或者关闭响应缓冲;

    5. “X-Accel-Charset”设置响应所需的字符集。

    2.7 proxy_hide_header

     
    1. 语法: proxy_hide_header field;

    2. 默认值: —

    3. 上下文: http, server, location

    nginx默认不会将“Date”、“Server”、“X-Pad”,和“X-Accel-...”响应头发送给客户端。proxy_hide_header指令则可以设置额外的响应头,这些响应头也不会发送给客户端。相反的,如果希望允许传递某些响应头给客户端,可以使用proxy_pass_header指令。

    2.8 proxy_pass_header

     
    1. 语法: proxy_pass_header field;

    2. 默认值: —

    3. 上下文: http, server, location

    允许传送被屏蔽的后端服务器响应头到客户端。

    2.9 proxy_cache_min_uses

     
    1. 语法: proxy_cache_min_uses number;

    2. 默认值: proxy_cache_min_uses 1;

    3. 上下文: http, server, location

    设置响应被缓存的最小请求次数。默认为1,当客户端发送相同请求达到规定次数后,nginx才对响应数据进行缓存;指定请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存

    2.10 proxy_cache_use_stale

     
    1. 语法: proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_404 | off ...;

    2. 默认值: proxy_cache_use_stale off;

    3. 上下文: http, server, location

    如果后端服务器出现状况,nginx是可以使用过期的响应缓存的。这条指令就是定义何种条件下允许开启此机制。这条指令的参数与proxy_next_upstream指令的参数相同。

    此外,updating参数允许nginx在正在更新缓存的情况下使用过期的缓存作为响应。这样做可以使更新缓存数据时,访问源服务器的次数最少。

    在植入新的缓存条目时,如果想使访问源服务器的次数最少,可以使用proxy_cache_lock指令。

    2.11 proxy_cache_lock

     
    1. 语法: proxy_cache_lock on | off;

    2. 默认值: proxy_cache_lock off;

    3. 上下文: http, server, location

    4. 这个指令出现在版本 1.1.12.

    开启此功能时,对于相同的请求,同时只允许一个请求发往后端,并根据proxy_cache_key指令的设置在缓存中植入一个新条目。 其他请求相同条目的请求将一直等待,直到缓存中出现相应的内容,或者锁在proxy_cache_lock_timeout指令设置的超时后被释放。如果不启用proxy_cache_lock,则所有在缓存中找不到文件的请求都会直接与服务器通信。

    2.12 proxy_cache_bypass

     
    1. 语法: proxy_cache_bypass string ...;

    2. 默认值: —

    3. 上下文: http, server, location

    定义nginx不从缓存取响应的条件。如果至少一个字符串条件非空而且非“0”,nginx就不会从缓存中去取响应:

     
    1. proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

    2. proxy_cache_bypass $http_pragma $http_authorization;

    本指令可和与proxy_no_cache一起使用。

    2.13 proxy_no_cache

     
    1. 语法: proxy_no_cache string ...;

    2. 默认值: —

    3. 上下文: http, server, location

    定义nginx不将响应写入缓存的条件。如果至少一个字符串条件非空而且非“0”,nginx就不将响应存入缓存:

     
    1. proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;

    2. proxy_no_cache $http_pragma $http_authorization;

    这条指令可以和proxy_cache_bypass指令一起使用。

    3. 其他一些配置

    3.1 proxy_cache_lock_timeout

     
    1. 语法: proxy_cache_lock_timeout time;

    2. 默认值: proxy_cache_lock_timeout 5s;

    3. 上下文: http, server, location

    这个指令出现在版本 1.1.12.

    为proxy_cache_lock指令设置锁的超时。

    3.2 proxy_read_timeout

     
    1. 语法: proxy_read_timeout time;

    2. 默认值: proxy_read_timeout 60s;

    3. 上下文: http, server, location

    定义从后端服务器读取响应的超时。此超时是指相邻两次读操作之间的最长时间间隔,而不是整个响应传输完成的最长时间。如果后端服务器在超时时间段内没有传输任何数据,连接将被关闭。

    3.3 proxy_connect_timeout

     
    1. 语法: proxy_connect_timeout time;默认值:

    2. proxy_connect_timeout 60s;

    3. 上下文: http, server, location

    设置与后端服务器建立连接的超时时间。应该注意这个超时一般不可能大于75秒。

    3.4 proxy_send_timeout

     
    1. 语法: proxy_send_timeout time;

    2. 默认值: proxy_send_timeout 60s;

    3. 上下文: http, server, location

    定义向后端服务器传输请求的超时。此超时是指相邻两次写操作之间的最长时间间隔,而不是整个请求传输完成的最长时间。如果后端服务器在超时时间段内没有接收到任何数据,连接将被关闭。

    3.5 proxy_http_version

     
    1. 语法: proxy_http_version 1.0 | 1.1;

    2. 默认值: proxy_http_version 1.0;

    3. 上下文: http, server, location

    这个指令出现在版本 1.1.4.

    设置代理使用的HTTP协议版本。默认使用的版本是1.0,而1.1版本则推荐在使用keepalive连接时一起使用。

    3.6 proxy_ignore_client_abort

     
    1. 语法: proxy_ignore_client_abort on | off;

    2. 默认值: proxy_ignore_client_abort off;

    3. 上下文: http, server, location

    决定当客户端在响应传输完成前就关闭连接时,nginx是否应关闭后端连接。

    3.7 proxy_intercept_errors

     
    1. 语法: proxy_intercept_errors on | off;

    2. 默认值: proxy_intercept_errors off;

    3. 上下文: http, server, location

    当后端服务器的响应状态码大于等于400时,决定是否直接将响应发送给客户端,亦或将响应转发给nginx由error_page指令来处理。

    3.8 proxy_next_upstream

     
    1. 语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_404 | off ...;

    2. 默认值: proxy_next_upstream error timeout;

    3. 上下文: http, server, location

    指定在何种情况下一个失败的请求应该被发送到下一台后端服务器:

     
    1. error

    2. 和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误;

    3. timeout

    4. 和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时;

    5. invalid_header

    6. 后端服务器返回空响应或者非法响应头;

    7. http_500

    8. 后端服务器返回的响应状态码为500;

    9. http_502

    10. 后端服务器返回的响应状态码为502;

    11. http_503

    12. 后端服务器返回的响应状态码为503;

    13. http_504

    14. 后端服务器返回的响应状态码为504;

    15. http_404

    16. 后端服务器返回的响应状态码为404;

    17. off

    18. 停止将请求发送给下一台后端服务器。

    需要理解一点的是,只有在没有向客户端发送任何数据以前,将请求转给下一台后端服务器才是可行的。也就是说,如果在传输响应到客户端时出现错误或者超时,这类错误是不可能恢复的。

     
    1. 语法: proxy_cookie_domain off;

    2. proxy_cookie_domain domain replacement;

    3. 默认值: proxy_cookie_domain off;

    4. 上下文: http, server, location

    这个指令出现在版本 1.1.15.

    设置“Set-Cookie”响应头中的domain属性的替换文本。 假设后端服务器返回的“Set-Cookie”响应头含有属性“domain=localhost”,那么指令

    proxy_cookie_domain localhost example.org;
    将这个属性改写为“domain=example.org”。

    domain和replacement配置字符串,以及domain属性中起始的点将被忽略。 匹配过程大小写不敏感。

    domain和replacement配置字符串中可以包含变量:

    proxy_cookie_domain www.$host $host;
    这条指令同样可以使用正则表达式。这时,domain应以“~”标志开始,且可以使用命名匹配组和位置匹配组,而replacement可以引用这些匹配组:

    proxy_cookie_domain ~\.(?P<sl_domain>[-0-9a-z]+\.[a-z]+)$ $sl_domain;

    可以同时定义多条proxy_cookie_domain指令:

     
    1. proxy_cookie_domain localhost example.org;

    2. proxy_cookie_domain ~\.([a-z]+\.[a-z]+)$ $1;

    off参数可以取消当前配置级别的所有proxy_cookie_domain指令:

     
    1. proxy_cookie_domain off;

    2. proxy_cookie_domain localhost example.org;

    3. proxy_cookie_domain www.example.org example.org;

     
    1. 语法: proxy_cookie_path off;

    2. proxy_cookie_path path replacement;

    3. 默认值: proxy_cookie_path off;

    4. 上下文: http, server, location

    这个指令出现在版本 1.1.15.

    设置“Set-Cookie”响应头中的path属性的替换文本。 假设后端服务器返回的“Set-Cookie”响应头含有属性“path=/two/some/uri/”,那么指令

    proxy_cookie_path /two/ /;

    将这个属性改写为“path=/some/uri/”。

    path和replacement配置字符串可以包含变量:

    proxy_cookie_path $uri /some$uri;

    这条指令同样可以使用正则表达式。如果使用大小写敏感的匹配,path应以“~”标志开始,如果使用大小写不敏感的匹配,path应以“~*”标志开始。path可以使用命名匹配组和位置匹配组,replacement可以引用这些匹配组:

    proxy_cookie_path ~*^/user/([^/]+) /u/$1;

    可以同时定义多条proxy_cookie_path指令:

     
    1. proxy_cookie_path /one/ /;

    2. proxy_cookie_path / /two/;

    off参数可以取消当前配置级别的所有proxy_cookie_path指令:

     
    1. proxy_cookie_path off;

    2. proxy_cookie_path /two/ /;

    3. proxy_cookie_path ~*^/user/([^/]+) /u/$1;

    3.11 proxy_pass

     
    1. 语法: proxy_pass URL;

    2. 默认值: —

    3. 上下文: location, if in location, limit_except

    设置后端服务器的协议和地址,还可以设置可选的URI以定义本地路径和后端服务器的映射关系。 这条指令可以设置的协议是“http”或者“https”,而地址既可以使用域名或者IP地址加端口(可选)的形式来定义:

    proxy_pass http://localhost:8000/uri/;

    又可以使用UNIX域套接字路径来定义。该路径接在“unix”字符串后面,两端由冒号所包围,比如:

    proxy_pass http://unix:/tmp/backend.socket:/uri/;

    如果解析一个域名得到多个地址,所有的地址都会以轮转的方式被使用。当然,也可以使用服务器组来定义地址。

    请求URI按下面规则传送给后端服务器:

    如果proxy_pass使用了URI,当传送请求到后端服务器时,规范化以后的请求路径与配置中的路径的匹配部分将被替换为指令中定义的URI:

     
    1. location /name/ {

    2. proxy_pass http://127.0.0.1/remote/;

    3. }

    如果proxy_pass没有使用URI,传送到后端服务器的请求URI一般客户端发起的原始URI,如果nginx改变了请求URI,则传送的URI是nginx改变以后完整的规范化URI:

     
    1. location /some/path/ {

    2. proxy_pass http://127.0.0.1;

    3. }

    在1.1.12版以前,如果proxy_pass没有使用URI,某些情况下,nginx改变URI以后,会错误地将原始URI而不是改变以后的URI发送到后端服务器。
    某些情况下,无法确定请求URI中应该被替换的部分:

    使用正则表达式定义路径。
    这种情况下,指令不应该使用URI。

    在需要代理的路径中,使用rewrite指令改变了URI,但仍使用相同配置处理请求(break):

     
    1. location /name/ {

    2. rewrite /name/([^/]+) /users?name=$1 break;

    3. proxy_pass http://127.0.0.1;

    4. }

    这种情况下,本指令设置的URI会被忽略,改变后的URI将被发送给后端服务器。

    后端服务器的地址,端口和URI中都可以使用变量:

    proxy_pass http://$host$uri;

    甚至像这样:

    proxy_pass $request;

    这种情况下,后端服务器的地址将会在定义的服务器组中查找。如果查找不到,nginx使用resolver来查找该地址。

    3.12 proxy_redirect

     
    1. 语法: proxy_redirect default;

    2. proxy_redirect off;

    3. proxy_redirect redirect replacement;

    4. 默认值: proxy_redirect default;

    5. 上下文: http, server, location

    设置后端服务器“Location”响应头和“Refresh”响应头的替换文本。 假设后端服务器返回的响应头是 “Location: http://localhost:8000/two/some/uri/”,那么指令

    proxy_redirect http://localhost:8000/two/ http://frontend/one/;

    将把字符串改写为 “Location: http://frontend/one/some/uri/”。

    replacement字符串可以省略服务器名:

    proxy_redirect http://localhost:8000/two/ /;

    此时将使用代理服务器的主域名和端口号来替换。如果端口是80,可以不加。

    用default参数指定的默认替换使用了location和proxy_pass指令的参数。因此,下面两例配置等价:

     
    1. location /one/ {

    2. proxy_pass http://upstream:port/two/;

    3. proxy_redirect default;

    4. location /one/ {

    5. proxy_pass http://upstream:port/two/;

    6. proxy_redirect http://upstream:port/two/ /one/;

    而且因为同样的原因,proxy_pass指令使用变量时,不允许本指令使用default参数。

    replacement字符串可以包含变量:

    proxy_redirect http://localhost:8000/ http://$host:$server_port/;

    而redirect字符串从1.1.11版本开始也可以包含变量:

    proxy_redirect http://$proxy_host:8000/ /;

    同时,从1.1.11版本开始,指令支持正则表达式。使用正则表达式的话,如果是大小写敏感的匹配,redirect以“~”作为开始,如果是大小写不敏感的匹配,redirect以“~*”作为开始。而且redirect的正则表达式中可以包含命名匹配组和位置匹配组,而在replacement中可以引用这些匹配组的值:

     
    1. proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $1$2;

    2. proxy_redirect ~*/user/([^/]+)/(.+)$ http://$1.example.com/$2;

    除此以外,可以同时定义多个proxy_redirect指令:

     
    1. proxy_redirect default;

    2. proxy_redirect http://localhost:8000/ /;

    3. proxy_redirect http://www.example.com/ /;

    另外,off参数可以使所有相同配置级别的proxy_redirect指令无效:

     
    1. proxy_redirect off;

    2. proxy_redirect default;

    3. proxy_redirect http://localhost:8000/ /;

    4. proxy_redirect http://www.example.com/ /;

    最后,使用这条指令也可以为地址为相对地址的重定向添加域名:

    proxy_redirect / /;

    3.13 proxy_set_header

     
    1. 语法: proxy_set_header field value;

    2. 默认值:

    3. proxy_set_header Host $proxy_host;

    4. proxy_set_header Connection close;

    5. 上下文: http, server, location

    允许重新定义或者添加发往后端服务器的请求头。value可以包含文本、变量或者它们的组合。 当且仅当当前配置级别中没有定义proxy_set_header指令时,会从上面的级别继承配置。 默认情况下,只有两个请求头会被重新定义:

     
    1. proxy_set_header Host $proxy_host;

    2. proxy_set_header Connection close;

    如果不想改变请求头“Host”的值,可以这样来设置:

    proxy_set_header Host       $http_host;

    但是,如果客户端请求头中没有携带这个头部,那么传递到后端服务器的请求也不含这个头部。 这种情况下,更好的方式是使用$host变量——它的值在请求包含“Host”请求头时为“Host”字段的值,在请求未携带“Host”请求头时为虚拟主机的主域名:

    proxy_set_header Host       $host;

    此外,服务器名可以和后端服务器的端口一起传送:

    proxy_set_header Host       $host:$proxy_port;

    如果某个请求头的值为空,那么这个请求头将不会传送给后端服务器:

     
    1. proxy_set_header Accept-Encoding "";

    2. 语法: proxy_ssl_session_reuse on | off;

    3. 默认值: proxy_ssl_session_reuse on;

    4. 上下文: http, server, location

    决定是否重用与后端服务器的SSL会话。如果日志中出现“SSL3_GET_FINISHED:digest check failed”错误,请尝试关闭会话重用。

    3.14 proxy_store

     
    1. 语法: proxy_store on | off | string;

    2. 默认值: proxy_store off;

    3. 上下文: http, server, location

    开启将文件保存到磁盘上的功能。如果设置为on,nginx将文件保存在alias指令或root指令设置的路径中。如果设置为off,nginx将关闭文件保存的功能。此外,保存的文件名也可以使用含变量的string参数来指定:

    proxy_store /data/www$original_uri;

    保存文件的修改时间根据接收到的“Last-Modified”响应头来设置。响应都是先写到临时文件,然后进行重命名来生成的。从0.8.9版本开始,临时文件和持久化存储可以放在不同的文件系统,但是需要注意这时文件执行的是在两个文件系统间拷贝操作,而不是廉价的重命名操作。因此建议保存文件的路径和proxy_temp_path指令设置的临时文件的路径在同一个文件系统中。

    这条指令可以用于创建静态无更改文件的本地拷贝,比如:

     
    1. location /images/ {

    2. root /data/www;

    3. open_file_cache_errors off;

    4. error_page 404 = /fetch$uri;

    5. }

    6.  
    7. location /fetch/ {

    8. internal;

    9.  
    10. proxy_pass http://backend/;

    11. proxy_store on;

    12. proxy_store_access user:rw group:rw all:r;

    13. proxy_temp_path /data/temp;

    14.  
    15. alias /data/www/;

    16. }

    或者像这样:

     
    1. location /images/ {

    2. root /data/www;

    3. error_page 404 = @fetch;

    4. }

    5.  
    6. location @fetch {

    7. internal;

    8.  
    9. proxy_pass http://backend;

    10. proxy_store on;

    11. proxy_store_access user:rw group:rw all:r;

    12. proxy_temp_path /data/temp;

    13.  
    14. root /data/www;

    15. }

     
    1. 语法: proxy_store_access users:permissions ...;

    2. 默认值: proxy_store_access user:rw;

    3. 上下文: http, server, location

    设置新创建的文件和目录的访问权限,比如:

    proxy_store_access user:rw group:rw all:r;

    如果指定了任何group或者all的访问权限,那么可以略去user的访问权限:

    proxy_store_access group:rw all:r;

    4. 其他一些问题

    4.1 缓存动态内容

    NGINX可以缓存动态内容,但是这不应该乱用,有些情况需要考虑

    首先,任何用户相关的数据不应被高速缓存。这可能导致一个用户的数据被呈现给其他用户。如果你的网站是完全静态的,这可能不是一个问题。

    如果你的网站有一些动态元素,你将不得不考虑到这一点。你如何处理要看是什么应用程序或服务器处理的后端处理。对于私人的内容,你应该设置Cache-Control头为“no-cache”,“no-sotre”,或者“private”依赖于数据的性质:

    4.2 缓存不生效问题

    nginx是否缓存是由nginx缓存服务器与源服务器共同决定的, 缓存服务器需要严格遵守源服务器响应的header来决定是否缓存以及缓存的时长。

    默认情况下,NGINX需要考虑从原始服务器得到的Cache-Control标头。当在响应头部中Cache-Control被配置为Private,No-Cache,No-Store或者Set-Cookie,NGINX不进行缓存。NGINX仅仅缓存GET和HEAD客户端请求。

    可以尝试通过更改头信息改让反代服务器缓存

    1、尝试修改源服务器代码,改变程序响应的头信息

    2、nginx反代配置提供了proxy_ignore_headers配置来忽略某些头信息,我们可以忽略引起反代不缓存的头信息

    proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie; 

    4.2 缓存过期问题

    引起缓存过期的因素

    • inactive:在proxy_cache_path配置项中进行配置,说明某个缓存在inactive指定的时间内如果不访问,将会从缓存中删除。
    • 源服务器php页面中生成的响应头中的Expires,生成语句为:
      header("Expires: Fri, 07 Sep 2013 08:05:18 GMT");
    • 源服务器php页面生成的max-age,生成语句为:
      header("Cache-Control: max-age=60");
    • nginx的配置项 proxy_cache_valid:配置nginx cache中的缓存文件的缓存时间,如果配置项为:proxy_cache_valid 200 304 2m;说明对于状态为200和304的缓存文件的缓存时间是2分钟,两分钟之后再访问该缓存文件时,文件会过期,从而去源服务器重新取数据。

    优先级

    • 在同时设置了源服务器端Expires、源服务器端max-age和nginx cahe端的proxy_cache_valid的情况下,以源服务器端设置的Expires的值为标准进行缓存的过期处理
    • 若在nginx中配置了相关配置项(proxy_ignore_headers,proxy_hide_header),取消原服务器端Expires对缓存的影响,在同时设置了源服务器端Expires、源服务器端max-age和nginx cahe端的proxy_cache_valid的情况下,以源服务器端max-age的值为标准进行缓存的过期处理
    • 若同时取消源服务器端Expires和源服务器端max-age对缓存的影响,则以proxy_cache_valid设置的值为标准进行缓存的过期处理
    • Inactive的值不受上述三个因素的影响,即第一次请求页面之后,每经过inactvie指定的时间,都要强制进行相应的缓存清理。因此inactive的优先级最高。

    详细的测试可以参照http://www.ttlsa.com/nginx/nginx-cache-priority/

    4.3 缓存清除问题

    nginx没有提供直接缓存清除的方法,但是我们可以使用以下方法清除

    1、但是可以通过使用第三方的模块ngx_cache_purge清除指定的URL
    需要加入一个新的location配置

     
    1. location ~ /purge(/.*) {

    2. proxy_cache_purge cache_one $host$1$is_args$args;

    3. }

    原网址和清除缓存的url对应关系

    www.firefoxbug.net/index.html ==>> www.firefoxbug.net/purge/index.html就能清除.

    2、直接删除指定的缓存文件

    直接想办法删除proxy_cache_path配置的目录下的所有文件,如果你可以直接操作linux那么可以直接rm -rf xxx了,如果不方便可以考虑写个脚本去删除相应的文件目录。

    4.4 缓存命中率

    nginx 提供了变量$upstream-cache-status 来显示缓存的命中状态,我们可以再nginx.conf配置中添加一个http响应头来显示这一状态

    反代配置中加入

     
    1. location / {

    2. proxy_pass http://zhengde.xxx.cn;

    3. proxy_set_header Host zhengde.xxx.cn;

    4. add_header X-Cache-Status $upstream_cache_status;

    5. ... 其他配置

    6. }

    在对客户端的响应中添加了一个X-Cache-StatusHTTP响应头,这样可以在响应信息中查看X-Cache-Status状态来判定是否命中

    如果想要统计命中率,那么在访问日志的格式中加入$upstream_cache_status记录即可

     
    1. log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘

    2. ‘$status $body_bytes_sent “$http_referer” ‘

    3. ’”$http_user_agent” “$http_x_forwarded_for”‘

    4. ’”$upstream_cache_status”‘;

    然后可以使用awk命令进行统计

     
    1. 命令:awk '{if($NF=="\"HIT\"") hit++} END {printf "%.2f%",hit/NR}' access.log

    2. 结果: 32.15%

    下面是$upstream_cache_status的可能值:

     
    1. 1.MISS——响应在缓存中找不到,所以需要在服务器中取得。这个响应之后可能会被缓存起来。

    2. 2.BYPASS——响应来自原始服务器而不是缓存,因为请求匹配了一个proxy_cache_bypass(见下面我可以在缓存中打个洞吗?)。这个响应之后可能会被缓存起来。

    3. 3.EXPIRED——缓存中的某一项过期了,来自原始服务器的响应包含最新的内容。

    4. 4.STALE——内容陈旧是因为原始服务器不能正确响应。需要配置proxy_cache_use_stale。

    5. 5.UPDATING——内容过期了,因为相对于之前的请求,响应的入口(entry)已经更新,并且proxy_cache_use_stale的updating已被设置。

    6. 6.REVALIDATED——proxy_cache_revalidate命令被启用,NGINX检测得知当前的缓存内容依然有效(If-Modified-Since或者If-None-Match)。

    7. 7.HIT——响应包含来自缓存的最新有效的内容。

    4.5 如何实现动静分离

     
    1. server

    2. {

    3. listen 10000;

    4. server_name localhost;

    5.  
    6. #静态处理交给nginx

    7. location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|ico|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma|css|js)$ {

    8. proxy_cache cache_one;

    9. proxy_cache_valid 200 304 302 2d;

    10. proxy_cache_valid any 1d;

    11. proxy_cache_key $host$uri$is_args$args;

    12. add_header X-Cache '$upstream_cache_status from $host';

    13.  
    14. proxy_pass http://127.0.0.1:8088;

    15. expires 30d;

    16. }

    17.  
    18. #动态文件不处理

    19. location / {

    20. proxy_pass http://127.0.0.1:8080;

    21. }

    22.  
    更多相关内容
  • Proxy ARP解析过程

    千次阅读 多人点赞 2022-01-20 20:36:06
    文章目录Proxy ARP产生原因:路由式Proxy ARP:ARP任意代理:VLAN内Proxy ARP:VLAN间Proxy ARP: Proxy ARP产生原因: ARP只适用于处于同一物理网络的相同网段主机之间的通信。网络中的交换机收到主机发送的ARP请求...

    Proxy ARP产生原因:

    ARP只适用于处于同一物理网络的相同网段主机之间的通信。网络中的交换机收到主机发送的ARP请求报文后,会检查报文的目的IP地址是否是本机的IP,以确定该报文请求的是不是本机的MAC地址。
    如果是,则回复ARP响应报文;如果不是;则丢弃该ARP请求报文。
    对于不在同一物理网络但属于相同网段的主机,或者在同一物理网络属于相同网段但不能二层互通的主机,可以在其之间的交换机上部署ARP代理功能,以实现这些主机之间的通信。部署ARP代理功能后,交换机收到ARP请求报文且发现其目的地址不是自己,则使用交换机自己的MAC地址以及目的主机的IP地址向源主机回复ARP响应报文,即交换机代替目的主机回复ARP响应报文。

    路由式Proxy ARP:

    如果主机属于同一网段却不在同一物理网络上并且连接主机的网关设备具有不同的网关地址,此时主机间要互通,则需要在交换机上连接主机的接口上启用路由式Proxy ARP功能。
    HostA的IP地址为10.10.10.1/16,HostB的IP地址为10.10.11.1/16,HostA与HostB处于同一网段。Switch通过VLANIF10和VLNAIF20连接两个网络,VLANIF10和VLANIF20的IP地址不在通一个网段。当HostA需要与HostB通信时,由于目的IP地址与本机的IP地址为同一个网段,因此HostA以广播形式发送ARP请求报文,请求HostB的MAC地址。但是,由于两台主机处于不同的物理网络(不同广播域)中,HostB无法收到HostA的ARP请求报文,因此也就无法应答。

    ●路由式Proxy ARP典型组网图
    在这里插入图片描述
    通过在Swithc的VLANIF10和VLANIF20上使能路由式Proxy ARP功能,可以解决上述问题。
    1、HostA发送ARP请求报文,请求目的主机HostB的MAC地址。
    2、Swithc收到此ARP请求报文后,检查报文的目的IP地址,发现并不是自己本机的IP,因此确定该报文请求的不是自己的MAC地址。然后,Swithc检查是否存在到达HostB的路由:
          a、如果没有到HostB的路由,则丢弃HostA发送的ARP请求报文
          b、如果有到HostB的路由,则判断接收报文的接口上是否使能了路由式Proxy ARP功能:
                如果使能了路由式Proxy ARP功能,则将VLANIF10的MAC地址通过ARP响应报文发送给HostA。
                HostA收到Swithc发送的ARP响应报文后,认为此报文是HostB发送的ARP响应报文。HostA从报文中学习Swithc设备VLANIF10的MAC地址,并使用此MAC地址向HostB发送数据报文。
                如果没有使能路由式Proxy ARP功能,则丢弃HostA发送的ARP请求报文。

    ARP任意代理:

    针对服务器划分VM的情况,为了使能VM能够在多个服务器或多个交换机间灵活部署与迁移,常用的方法是将多个交换机间的二层连通。但是,这种方式会导致网络中二层域变大,并存在广播风暴的风险。为了解决这一问题,常用的方式是将VM的网关部署在接入交换机上,同时开启ARP任意代理,将网关设备端口的MAC地址发送给请求的VM,将VM到其他VM的通讯都转变为路由转发。
    VM的IP地址为10.10.10.1/24,VM2的IP地址为10.10.10.4/24,VM1与VM2处于同一网段。Swithc1和Swithc2通过IP地址、MAC地址相同的VLANIF10连接两个网络。当VM1需要与VM2通信时,由于目的IP地址与本机的IP地址为同一网段,因此VM1以广播形式发送ARP请求报文,请求VM2的MAC地址。但是,由于两台主机处于不同的物理网络(不同广播域)中,VM无法收到VM1的ARP请求报文,因此也无法应答。

    ●ARP任意代理典型组网图
    在这里插入图片描述
    通过Swithc1、Swithc2的VLANIF10上使能ARP任意代理功能,可以解决上述问题。
    1、VM1发送ARP请求报文,请求目的主机VM2的MAC地址。
    2、Swithc1收到此ARP请求报文后,检查报文的目的IP地址,发现并不是自己本机的IP,因此确定该报文请求的不是自己的MAC地址。然后,Swithc检查接收报文的接口上是否使能了ARP任意代理功能:
          a、如果使能了ARP任意代理功能,则将VLANIF10的MAC地址通过ARP响应报文发送给VM1。
                VM1收到Swithc1发送的ARP响应报文后,认为此报文是VM2发送的ARP响应报文。
                VM1从报文中学习Swithc1设备VLANIF10的AMC地址,并使用此MAC地址向VM2发送数据报文。
          b、如果没有使能ARP任意代理功能,则丢弃VM发送的ARP请求报文。

    VLAN内Proxy ARP:

    如果主机属于相同的VALN,但VLAN内配置了二层端口隔离,此时主机间要互通,则需要在关联VLAN的接口上启用VLAN内Proxy ARP功能。
    HostA和HostB是Switch下的两个主机。连接HostA和HostB的两个接口在Switch属于同一个VLAN 4。由于在Switch上配置了VLAN内的二层端口隔离,因此HostA和HostB不能直接接在二层互通。

    ●VLAN内Proxy ARP典型组网图
    在这里插入图片描述
    通过在Switch的VLANIF4上使能VLAN内Proxy ARP功能,可以解决上述问题。
    1、HostA发送ARP请求报文,请求目的主机HostB的MAC地址。
    2、Switch收到此ARP请求报文后,检查报文的目的IP地址,发现并不是自己本机的IP,因此确定该报文请求的不是自己的MAC地址。然后,Switch检查是否存在到达HostB的ARP表:
          a、如果HostB对应的ARP表项,且该表项中的VLAN信息与接收报文的端口的VLAN信息相同,则判断关联VLAN的接口是否使能了VLAN内Proxy ARP功能:
                如果使能了VLAN内Proxy ARP功能,则将VLANIF4的MAC地址发送给HostA。
                HostA收到Switch发送的ARP响应报文后,认为此报文是HostB发送的ARP响应报文。
                HostA从报文中学习Switch设备VLANIF4的MAC地址,并使用此MAC地址向HostB发送数据报文。
                如果没有使能VLAN内Proxy ARP功能,则丢弃该ARP请求报文。

          b、如果没有HostB对应的ARP表项,则丢弃HostA发送的ARP请求报文,同时判断关联VLAN的接口是否使能了VLAN内Proxy ARP功能:
                如果使能了VLAN内Proxy ARP功能,则在VLAN4内广播发送ARP请求报文,该请求报文的目的IP地址为HostB的IP地址。收到HostB发送的ARP响应报文后,生成响应的ARP表项。
                如果没有使能VLAN内Proxy ARP功能,则不进行任何操作。

    VLAN间Proxy ARP:

    如果主机处于同一物理网络相同网段但属于不同的VLAN,主机间要进行三层互通,则需要在关联这些VLAN的接口上使能VLAN间Proxy ARP功能。
    HostA和HostB是Switch下的两个用户,HostA和HostB处于相同网段,但HostA属于VLAN3,HostB属于VLAN2,。由于HostA和HostB属于不同的Sub-VLAN,HostA和HostB不能直接实现二层互通。

    ●VLAN间Proxy ARP典型组网图
    在这里插入图片描述
    通过在Switch的VLANIF4上使能VLAN间Proxy ARP功能,可以解决上述问题。
    1、HostA发送ARP请求报文,请求目的主机HostB的MAC地址。
    2.Switch收到此ARP请求报文后,检查报文的目的IP地址,发现并不是自己本机的IP,因此确定该报文请求的不是自己的MAC地址。然后,Switch检查是否存在到达HostB的ARP表:
         a、 如果有HostB对应的ARP表项,且该表项中的VLAN信息与接收报文的端口的VLAN信息不同,则判断关联VLAN的接口是否使能了VLAN间Proxy ARP功能:
                如果使能了VLAN间Proxy ARP功能,则将VLANIF4的MAC地址发送给HostA。
                HostA收到Switch发送的ARP响应报文后,认为此报文是HostB发送的ARP响应报文。
                HostA从报文中学习Switch设备VLANIF4的MAC地址,并使用此MAC地址向HostB发送数据报文。
                如果没有使能VLAN间Proxy ARP功能,则丢弃该ARP请求报文。
          b、如果没有HostB对应的ARP表项,则丢弃HostA发送的ARP请求报文,同时判断关联VLAN的接口是否使能了VLAN间Proxy ARP功能:
                如果使能了VLAN间Proxy ARP功能,则在VLAN2内广播发送ARP请求报文,该请求报文的目的IP地址为HostB的IP地址。
                收到HostB发送的ARP响应报文后,生成响应的ARP表项。
                如果没有使能VLAN间Proxy ARP功能,则不执行任何操作。

    展开全文
  • Proxy使用详解

    千次阅读 2020-09-28 19:28:39
    来源 |https://www.cnblogs.com/chuaWeb/p/13676000.html通用1、Proxy可以包装任何形式的对象:包括原生数组,函数,甚至另一个代理。2、...

    来源 | https://www.cnblogs.com/chuaWeb/p/13676000.html

    通用

    1、Proxy可以包装任何形式的对象:包括原生数组,函数,甚至另一个代理。
    2、代理实例中没有指定的handler,实际就是操作原对象target:实例:打开控制台查看:http://jsrun.net/3RLKp/edit

    let target = function(){return 'ddd'}let proxy = new Proxy(target, {});proxy.prototype.age = 12console.log(proxy.prototype === target.prototype) // true
    

    3、代理实例只是返回对象target的一个代理包装(只有在触发handler时,handler中可以操作target),target的更改不会触发代理实例的handler:实例:打开控制台查看:http://jsrun.net/7BLKp/edit

    来看一下具体的运用
    MDN上有一个实例比较特别【拓展构造函数】,来看一下:在线例子:http://jsrun.net/cRLKp/edit

    function extend(sup, base) {  var descriptor = Object.getOwnPropertyDescriptor(    base.prototype, 'constructor'  );  base.prototype = Object.create(sup.prototype);  var handler = {    construct: function(target, args) {      var obj = Object.create(base.prototype);      this.apply(target, obj, args);      return obj;    },    apply: function(target, that, args) {      sup.apply(that, args);      base.apply(that, args);    }  };  var proxy = new Proxy(base, handler);  descriptor.value = proxy;  Object.defineProperty(base.prototype, 'constructor', descriptor);  return proxy;}
    var Person = function(name) {  this.name = name;};
    var Boy = extend(Person, function(name, age) {  this.age = age;});
    Boy.prototype.gender = 'M';
    var Peter = new Boy('Peter', 13);
    console.log(Peter.gender);  // "M"console.log(Peter.name);    // "Peter"console.log(Peter.age);     // 13
    

    执行完Boy.prototype.gender = 'M'后,数据结构是下面这个样子的

    执行 var Peter = new Boy('Peter', 13);
    new操作进入到handler.construct,里面的上下文环境this绑定在handler(可以查看MDN文档描述)。直接调用this.apply进入handler.apply执行。new操作执行完毕之后的数据结构

    巧妙利用原型链和代理

    handler形参中的receiver

    receiver是代理或继承代理的对象。通俗来讲,就是触发了handler的源头对象。一般receiver即是target的代理实例。
    但是如果对象继承了代理对象的情况,如下:

    "use strict"const proxy = new Proxy({}, {    get: function(target, prop, receiver) {        if(proxy === receiver){            console.log('receiver为proxy')        }        else if(obj === receiver){            console.log('receiver为obj')        }else{            console.log('receiver不为proxy也不为obj')        }        return 'chua';    }});proxy.dd // receiver为proxylet obj = Object.create(proxy);obj.msg // receiver为obj
    

    proxy对象是obj对象的原型,obj对象本身并没有msg属性,所以根据原型链,会在proxy对象上读取该属性,导致被拦截。
    obj是obj.msg触发handler的原始调用(源头)

    handler.set

    set必须返回一个boolean类型

    必须返回一个boolean类型,true表示设置成功,返回false表示失败,严格模式下会抛错(下面的例子全部在严格模式下执行)
    注意:返回的数据如果不是boolean类型,会转换成布尔类型,假值包括:undefined,null,false, +0, -0, NaN, "" :实例

    const target = {  msg: "hello"};
    const handler = {    set: function(target, prop, value, receiver){        target[prop] = value        // return true    }};
    const proxy = new Proxy(target, handler);proxy.msg = 'wow' // Uncaught TypeError: 'set' on proxy: trap returned falsish for property 'msg'
    

    handler.set在以下情况会抛错
    1、如果相应的目标对象属性是不可写的数据属性,则无法将属性的值更改为与相应目标对象属性的值不同的值。实例:严格模式

    var obj = {}Object.defineProperty(obj, 'year', {     // configurable: false, 默认false    // writable: false, 默认false    value: 2})Object.defineProperty(obj, 'class', {     configurable: true,     // writable: false, 默认false    value: 'chua'})var proxy = new Proxy(obj, {    set(target, prop, val){        target[prop] = val        return true    }})proxy.card = 'sdf' // 设置成功proxy.year = 10 // Uncaught TypeError: Cannot assign to read only property 'year' of object proxy.class = 'dd' // Uncaught TypeError: Cannot assign to read only property 'class' of object
    

    2、如果相应的目标对象属性配置了[[Set]]为undefined,实例

    var obj = {}const definereactive =  function(data, key, val) {    Object.defineProperty(data, key, {        get: function(){            return val        },        set: undefined // 应该设置成下面这个正确的函数        // function(newVal) {        //     val = newVal;        // }    });}definereactive(obj, 'year', obj.year)var proxy = new Proxy(obj, {    set(target, prop, val){        target[prop] = val        return true    }})obj.year = 20 // Uncaught TypeError: Cannot set property year of #<Object> which has only a getterproxy.year = 30 // Uncaught TypeError: Cannot set property year of #<Object> which has only a getter
    

    3、在严格模式下,handler.set错误返回值(转换为boolean后为false)将引发TypeError异常。

    复杂对象

    Proxy只对其根属性(原型链上的也算)的值的更改做监听,如果某个属性key对应的值为一个引用类型,引用地址没有发生改变则不会进入到handler.set

    const target = {    info: {        name: 'chua',        age: 18    }};
    const handler = {    set: function(target, prop, value, receiver){        console.log('in handler.set', target, prop, value, receiver)        target[prop] = value        return true    }};
    const proxy = new Proxy(target, handler);proxy.info.name = 'chua1989' // 没有进入handler.set, 需要直接更改info属性才行console.log(proxy.info.name) // chua1989
    

    handler.has

    报错的情况
    1、target的某属性为不可配置,则该属性不能被代理隐藏(即handle.has不能返回false): 在线运行

    var obj = {}Object.defineProperty(obj, 'year', {    configurable: false,    value: 2})var proxy = new Proxy(obj, {    has: function(target, prop) {        console.log('called: ' + prop);        return false;    }})console.log('year' in proxy); // Uncaught TypeError: 'has' on proxy: trap returned falsish for property 'year' which exists in the proxy target as non-configurable
    

    2、target对象不可拓展,则已经存在的属性不能被代理隐藏:在线运行

    var obj = { year: 2}Object.preventExtensions(obj);
    var proxy = new Proxy(obj, {    has: function(target, prop) {        console.log('called: ' + prop);        return false;    }})console.log('a' in proxy); // 不存在的属性没有问题console.log('year' in proxy); // Uncaught TypeError: 'has' on proxy: trap returned falsish for property 'year' but the proxy target is not extensible
    

    handler.construct

    只有当target能使用new方法该配置才能起作用。即target必须是函数

    const p = new Proxy({}, {    construct: function(target, argumentsList, newTarget) {        return function(){};    }});
    new p(); // proxy.html:16 Uncaught TypeError: p is not a constructor
    

    而且handler.construct必须返回一个Object引用类型就行

    const p = new Proxy(function() {}, {  construct: function(target, argumentsList, newTarget) {    return 1;  }});
    new p(); // TypeError is thrown
    

    下面这个就不会报错

    const p = new Proxy(function() {}, {    construct: function(target, argumentsList, newTarget) {        return function(){};    }});
    new p();
    

    handler.construct中的this指向的是handler

    handler.deleteProperty

    deleteProperty 必须返回一个 Boolean 类型的值,表示了该属性是否被成功删除。严格模式下false会报错

    var p = new Proxy({}, {    deleteProperty: function(target, prop) {        console.log('called: ' + prop);        return false;    }});
    delete p.a; // "called: a"
    

    如果目标对象的属性是不可配置的,那么该属性不能被删除

    var obj = {}Object.defineProperty(obj, 'a', {    configurable: false})var p = new Proxy(obj, {    deleteProperty: function(target, prop) {        console.log('called: ' + prop);        return true;    }});
    delete p.a; // "called: a" // Uncaught TypeError: 'deleteProperty' on proxy: trap returned truish for property 'a' which is non-configurable in the proxy target
    

    handler.defineProperty

    如果目标对象不可扩展(non-extensible),则defineProperty()不能增加目标对象上不存在的属性,否则会报错。
    如果目标对象的某个属性不可写(writable)或不可配置(configurable),则defineProperty()方法不得改变这两个设置(这是Object.defineProperty的特性)。

    handler.getPrototypeOf

    如果遇到了下面两种情况,js 引擎会抛出 TypeError 异常:
    getPrototypeOf() 方法返回的不是对象也不是 null。
    目标对象是不可扩展的,且 getPrototypeOf() 方法返回的原型不是目标对象本身的原型。

    handler.isExtensible

    isExtensible方法必须返回一个 Boolean值或可转换成Boolean的值。
    Object.isExtensible(proxy) 必须同Object.isExtensible(target)返回相同值。也就是必须返回true或者为true的值,返回false和为false的值都会报错。

    handler.ownKeys

    有三类属性会被ownKeys()方法自动过滤,不会返回。
    1、目标对象上不存在的属性
    2、属性名为 Symbol 值
    3、不可遍历(enumerable)的属性

    如果违反了下面的约束,proxy将抛出错误 TypeError:
    1、ownKeys 的结果必须是一个数组.
    2、数组的元素类型要么是一个 String ,要么是一个 Symbol.
    3、结果列表必须包含目标对象的所有不可配置(non-configurable )、自有(own)属性的key.
    4、如果目标对象不可扩展,那么结果列表必须包含目标对象的所有自有(own)属性的key,不能有其它值.

    handler.preventExtensions

    如果目标对象是可扩展的,那么只能返回 false。否则抛错

    handler.setPrototypeOf

    如果 target 不可扩展, 原型参数必须与Object.getPrototypeOf(target) 的值相同. 否则抛错
    如果你不想为你的对象设置一个新的原型,你的handler's的setPrototypeOf方法可以返回false,也可以抛出异常。

    var handlerReturnsFalse = {    setPrototypeOf(target, newProto) {        return false;    }};
    var newProto = {}, target = {};
    var p1 = new Proxy(target, handlerReturnsFalse);Object.setPrototypeOf(p1, newProto); // throws a TypeErrorReflect.setPrototypeOf(p1, newProto); // returns false
    

    为什么Object和Reflect调用setPrototypeOf结果会不同。这便是Reflect被例入标准的一个原因之一:操作对象时出现报错返回false。这样可以直接使用如下的方式

    if(Reflect.setPrototypeOf(p1, newProto)){ ...}
    

    handler的属性方法中的this

    正常情况,handler的属性方法中this指向的是proxy实例,而不是target,要特别注意

    const target = new Date();const handler = {};const proxy = new Proxy(target, handler);
    proxy.getDate();// TypeError: this is not a Date object.
    

    由于getDate必须要是Date实例才能有作用,所以此处报错。

    handler.construct中的this指向的是handler

    展开全文
  • pip:ProxyError(‘Cannot connect to proxy.

    万次阅读 多人点赞 2021-07-25 17:45:08
    connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy.', OSError(0, 'Error'))': /pypi/simple/scrapy/ WARNING: Retrying (Retry(total=3, ...

    1 问题

    在打开科学上网软件(后面简称XX)的前提下,pip安装python库失败(此时源为阿里源,XX设置为DIRECT,也就是直连,访问国内网站的),pip报错:

    Looking in indexes: https://mirrors.aliyun.com/pypi/simple/
    WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy.', OSError(0, 'Error'))': /pypi/simple/scrapy/
    WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy.', OSError(0, 'Error'))': /pypi/simple/scrapy/
    WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy.', OSError(0, 'Error'))': /pypi/simple/scrapy/
    WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy.', OSError(0, 'Error'))': /pypi/simple/scrapy/
    WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy.', OSError(0, 'Error'))': /pypi/simple/scrapy/
    ERROR: Could not find a version that satisfies the requirement scrapy
    ERROR: No matching distribution found for scrapy
    

    2 初步尝试

    出现了问题之后就试着解决,看错误信息是和代理有关,因此退出XX,再次pip,没有问题。考虑到pip不会经常用,因此这种解决办法似乎完全可以接受,但我有强迫症呀,想找一个让XX始终运行,一劳永逸的解决办法,于是开始在网上搜索,这一搜,啥牛鬼蛇神都出来了(大家能不能好好写博客,不要你抄他抄,搞的信息好混乱,检索效率极低,如果引用,那么需要指出来源),先看看大家伙都怎么办的。

    2.1 设置环境变量

    设置环境变量如下:

    HTTP_PROXY        http://127.0.0.1:7890
    HTTPS_PROXY       http://127.0.0.1:7890
    

    确实有效,但很多博客并未给出这么做的原因,而且环境变量影响比较广,我有强迫症啊,只要有一点办法,都要坚决维护环境变量的干净整洁。

    2.2 修改注册表(这是一个夺笋的解决方案呀)

    修改注册表,将ProxyEnable从1修改为0(图片来自网络,找不到根源在哪了):
    在这里插入图片描述
    为什么说它损呢,是因为这么一搞代理就被关闭了,XX也就发挥不了作用了,我就为用一次pip,这么干真的合适吗?这样干还不如直接把XX退出呢,右键退出多方便,要用的时候再打开,犯得着修改注册表?最开始这么干的人可能情况比较特殊吧,可能他以后都不在用XX类软件了,并且之前用的XX类软件很拉跨,退出的时候不会关闭系统代理设置,导致奇怪的网络问题,于是他一气之下干脆把代理直接禁了…我编不下去了,确实理解不了为什么有人这么干。

    2.3 pip的代理设置

    为pip做相应的代理设置,具体做法有以下几种(关于XX的IP和端口号根据个人实际来确定):

    • 使用pip的--proxy选项设置代理:pip install libname --proxy http://127.0.0.1:7890
    • 直接编辑pip的配置文件pip.ini,在其中的[global]下面添上一行proxy = http://127.0.0.1:7890
    • 使用pip的config命令来写配置文件:pip config set global.proxy http://127.0.0.1:7890

    按理来说,这和设置环境变量原理应该是一样的,都是把代理的情况告知pip,只是环境变量作用于全局,而这种方式仅仅针对pip。但,诡异的是,上述做法完全没有效果。不用修改环境变量,这本该成为我理想的选择,但它没效。强迫症患者不能忍啊,到底是为什么呢?见下文!

    3 找问题的根源

    遇到了奇怪的事情,但看源码去解决这个问题对当前的我来说又不现实,只能加大搜索力度了。运气比较好,终于找到了深入剖析这个问题的资料,见参考文献。由于对pip的相关背景不是太了解,且时间有限,所以只看懂了个大概,下面概括一下我的理解(需要深入理解的就去结合参考文献看源码吧)。

    3.1 问题的根源

    • 代理服务器只支持HTTP(不确定是XX的锅还是windows的锅),且pip安装库时使用的urllib3在以前也就是低版本的时候是不支持HTTPS的,这样一来,尽管我们的源可能是HTTPS的,比如阿里源https://mirrors.aliyun.com/pypi/simple/,但走的还是HTTP,这正称了代理服务器的心,因此工作起来没有问题。
    • 后来也就是新版本的urllib3支持HTTPS了,但代理服务器不支持,这时候就出问题了:pip通过HTTPS去找代理,但由于代理服务器只支持HTTP,没法处理请求,因此在ssl握手阶段就出错了(连接不上代理)。
    • 关于2.3节的做法为什么没有效,是因为通过--proxy或配置文件所作的代理设置没有被更正到urllib的request。

    3.2 解决办法

    知道问题的根源就好办了,无非是对症下药。下面分别从代理、源、pip三个方面入手,给出不同的解决办法。

    3.2.1 从代理入手

    既然事情的是因为代理服务器不支持HTTPS导致的,那么不要用代理就行了,也就是在pip的时候,退出一下XX,后面要用了再启动就是了。2.2的方法之所以生效,也是因为解决了代理,每错,解决的干净彻底。

    3.2.2 从源入手

    既然XX不支持HTTPS,那我们就不能称一下它脆弱的心?毕竟人家上网的时候帮了咱很多吧。简单的说,咱们不使用带S的源就可以了呀,虽然安全性上有损失,但大公司或知名高校维护的源还是可以信任的。具体做法,通过命令或直接编辑来修改pip的配置文件:

    [global]
    index-url = http://mirrors.aliyun.com/pypi/simple/
    
    [install]
    trusted-host = mirrors.aliyun.com
    

    值得一提的是,不使用安全HTTP协议时,我们要告诉pip我们信任该源(trusted-host),否则pip会撂挑子:

    WARNING: The repository located at mirrors.aliyun.com is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow it anyway with '--trusted-host mirrors.aliyun.com'.
    ERROR: Could not find a version that satisfies the requirement libname
    ERROR: No matching distribution found for libname
    

    这种方法比较适合我这种强迫症患者,因为操作简单,且完全不会影响到pip之外。

    3.2.3 从pip入手

    pip十分痴迷HTTPS,但XX确实不支持,这时不妨坦诚一些,把XX的情况告诉pip,希望pip能理解和支持。没错,这里要做的就是2.1节2.3节所做的。不过,上文已经说了,2.1节的办法有效,而2.3节的办法无效。因为配置文件也好、--proxy选项也好,咱们对代理的设置都没起效,pip还是从系统获取代理(所以设置系统环境变量有效),这算不算pip的bug呢?具体解决办法,GitHub上有网友提出修改python安装目录/Python37/Lib/site-packages/pip/_internal/network下的session.py(我的是python3.7,具体目录根据个人实际确定)。修改位于419行附近,原先是:

    def request(self, method, url, *args, **kwargs):
            # Allow setting a default timeout on a session
            kwargs.setdefault("timeout", self.timeout)
            
            # Dispatch the actual request
            return super().request(method, url, *args, **kwargs)
    

    修改为:

    def request(self, method, url, *args, **kwargs):
            # Allow setting a default timeout on a session
            kwargs.setdefault("timeout", self.timeout)
            
            # fix problem with proxies make pip --proxy work
            # this method comes from https://github.com/pypa/pip/issues/9216 (junqfisica's comment)
            kwargs.setdefault("proxies", self.proxies)
    
            # Dispatch the actual request
            return super().request(method, url, *args, **kwargs)
    

    这样一来,2.3节的办法就可以工作啦。不过修改python自带源码的行为终究让人感觉不太对劲。这个看个人吧,我还是比较推荐3.2.2节的做法,毕竟还讲啥安全呀,各种安全协议倒是层出不穷,与此同时,个人信息都不知道被卖了多少手了。

    4 写在最后

    到处乱抄博客,污染网络环境的,原地爆炸、螺旋升天!技术社区和氛围需要大家一起来维护,谢谢观看。

    参考文献

    [1] https://github.com/pypa/pip/issues/9216
    [2] https://zhuanlan.zhihu.com/p/350015032

    展开全文
  • Es6新特性Proxy代理用法解析

    千次阅读 2021-09-25 10:50:52
    什么是ProxyProxy 对象是ES6新出的一个特性,用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。 需要知道的是,在Vue2中双向数据绑定原理(数据劫持)采用...
  • esri.config.defaults.io.proxyUrl is not set所缺文件 proxy.jsp、proxy.ashx、proxy.php、proxy.config
  • proxy 服务器配置

    千次阅读 2022-03-28 20:05:56
    Proxy在局域网,对内网和外网均有作用。 [root@paly ~]#yum install squid Loaded plugins: fastestmirror Setting up Install Process Repository base is listed more than once in the configuration Loading ...
  • nginx的反向代理proxy_pass指令

    万次阅读 多人点赞 2020-12-23 17:37:46
    nginx的反向代理proxy_pass指令 1. 首先什么是代理服务器? 客户机发送请求时,不会直接发送到目的主机,而是先被代理服务器收到,代理服务器收到客服机的请求后,再向目的机发出,目的机就会返回数据给客户机,在...
  • proxy_pass和proxy_set_header浅析

    千次阅读 2022-04-17 21:25:57
    部署项目,编辑Nginx配置文件时,用到了proxy_pass和proxy_set_header,由于之前用的比较少,所以顺便去了解一波 proxy_pass ​ #结尾不加/ location /abc/ { proxy_pass http://10.1.12.123:8080; } #结尾添加/ ...
  • mod_proxy 下载

    热门讨论 2013-01-22 19:21:55
    列表包含 mod_proxy.so mod_proxy_http.so mod_proxy_ajp.so mod_proxy_ftp.so mod_proxy_connect.so mod_proxy_balancer.so
  • JavaScript 的 Proxy详解

    千次阅读 多人点赞 2019-09-02 11:12:30
    Proxy详解零、引言一、Proxy是什么?1.1 理解Proxy1.2 Proxy怎么用1.3 可以拦截的操作1.4 this的指向二、Proxy能干什么?2.1 get()2.2 set()2.3 apply()2.4 construct ()三、Vue中的Proxy和Object.defineProperty3.1...
  • 常见的Proxy源码分析

    千次阅读 2019-09-10 19:26:42
    文章目录一 描述二 源码三 dubbo的Proxy 一 描述 dubbo的源码中,还有两个关于javassist技术和jdk proxy的扩展, javassist:动态编程,通过jdk中的JavaCompiler接口,能够直接对一个已经存在java class文件进行...
  • 1、proxy_set_header指令 该模块需要读取的配置文件。在这里,所有设置的值的含义和http请求体中的含义完全相同,除了Host外还有X-Forward-For proxy_set_header Host $http_host; proxy_set_header X-Forward-For $...
  • centos搭建proxypool

    万次阅读 2022-01-22 19:43:53
    centos搭建proxypool抓取免费节点
  • 2. Proxy 实例的方法 2.1get() 2.2set() 2.3apply() 2.4has() 2.5construct() 2.7deleteProperty() 2.8defineProperty() 2.9getOwnPropertyDescriptor() 2.10getPrototypeOf() 2.11isExtensible() 2.12...
  • named pipe tcp proxy

    热门讨论 2012-11-06 20:25:01
    named pipe tcp proxy
  • 本文为joshua317原创文章,转载请注明:转载自joshua317博客nginx正向代理,支持https模块:ngx_http_proxy_connect_module - joshua317的博客 文档地址:...
  • 深入浅出 proxy 系列之一:Proxy 是什么

    千次阅读 多人点赞 2021-03-19 11:53:30
    1. 理解proxy 1.1 类还是函数 proxy 是 ES6 中新增的一个函数,也可以叫类,但是 js 中一切皆是函数,即使使用 class 定义的类,最终也是函数,所以我们还是称其为函数吧,虽然我更喜欢称其为类,因为这更符合我...
  • vue3.0发布后,在双向数据绑定这里,使用proxy代替了object.defineProperty,众所周知,obj.defineProperty是对对象属性监听,循环对象,一个个属性监听,proxy是对一整个对象进行监听。而proxy的一大优势就是可以...
  • 什么是 ProxyProxy的简单例子

    千次阅读 2020-05-25 23:14:24
    .Proxy 是 ES6 中新增的一个特性,翻译过来意思是"代理",用在这里表示由它来“代理”某些操作。 Proxy 让我们能够以简洁易懂的方式控制外部对对象的访问。其功能非常类似于设计模式中的代理模式。 Proxy 可以理解成...
  • Proxy是什么?

    千次阅读 2022-03-20 15:21:58
    文章目录前言一、Proxy是什么二、Proxy的特性1.匿名性2.高可用3.缓存4.中转5.管控总结 前言 今天主要简单的讲一下proxy是什么? 一、Proxy是什么 Proxy指的是代理软件或代理服务器,也可以认为是一种网络访问方式...
  • proxy config

    千次阅读 2021-12-16 13:58:07
    touch proxyon.txt: export http_proxy=http://172.16.1.15:8080 export no_proxy="127.0.0.1,localhost,.localdomain.com" export https_proxy=$http_proxy \ ftp_proxy=$http_proxy \...HTTP_PROXY=$http_proxy \
  • ES6之Proxy代理

    万次阅读 2019-12-20 23:17:43
    什么是Proxy代理 ES6 让开发者能进一步接近 JS 引擎的能力,这些能力原先只存在于内置对象上。语言通过代 理( proxy )暴露了在对象上的内部工作,代理是一种封装,能够拦截并改变 JS 引擎的底 层操作。 人话是:把...
  • Vue3都使用Proxy了,你更应该了解Proxy

    千次阅读 2019-10-22 12:12:35
    vue3.0的pre-alpha版代码已经开源了,就像作者之前放出的消息一样,其数据响应这一部分已经由ES6的Proxy来代替Object.defineProperty实现,感兴趣的同学可以看其实现源码。vue都开始使用Proxy来实现数据的响应式了,...
  • js 中代理Proxy的方法以及Reflect

    千次阅读 2020-08-18 11:52:03
    js 中代理Proxy的方法以及Reflect apply(target, ctx, args) apply(target, object, args):三个参数,分别是 目标对象(目标对象得是函数) 目标对象的上下文对象(this)(需要手动设置的) 目标对象的参数数组。 ...
  • Object.defineProperty和Proxy区别

    万次阅读 多人点赞 2020-07-15 15:00:26
    const p = new Proxy(target, handler) 参数 target: 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。 handler: 一个通常以函数作为属性的对象,各属性中的函数分别...
  • Vue配置proxy

    万次阅读 2021-01-05 12:52:58
    文章目录后台前台配置 proxy请求示例请求结果 后台 const express = require('express') const app = new express() app.get('/api/news', (req, res) => { // res.setHeader("Access-Control-Allow-Origin", '...
  • 房东(Host)要出租房子,使用中介(Proxy)代理。 Rent 接口只有一个rent(出租)方法; 接口: public interface Rent {//租房 void rent(); } 房东: public class Host implements Rent{//房东 public ...
  • GO GOPROXY代理设置

    千次阅读 2022-04-28 10:13:58
    GO GOPROXY
  • Linux proxy 设置

    千次阅读 2021-06-08 09:52:56
    这里写自定义目录标题全局proxyubuntu apt repo proxy 全局proxy 更新 /etc/environment http_proxy=http://10.0.0.1:8080 https_proxy=http://10.0.0.1:8080 ftp_proxy=http://10.0.0.1:8080 no_proxy="127.0.0.1,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 951,350
精华内容 380,540
关键字:

proxy

友情链接: filtering.rar