Nginx反向代理中使用proxy_redirect重定向url
在使用Nginx做反向代理功能时,有时会出现重定向的url不是我们想要的url,这时候就可以使用proxy_redirect进行url重定向设置了。proxy_redirect功能比较强大,其作用是对发送给客户端的URL进行修改!!
语法:proxy_redirect [ default|off|redirect replacement ];
默认:proxy_redirect default;
配置块(使用的字段):http、server、location
当上游服务器返回的响应是重定向或刷新请求(如HTTP响应码是301或者302)时,proxy_redirect可以重设HTTP头部的location或refresh字段。
1 2 3 | location /login { proxy_pass http: //target_servers/login ; } |
如果需要修改从被代理服务器传来的应答头中的"Location"和"Refresh"字段,这时候就可以用proxy_redirect这个指令设置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 假设被代理服务器返回Location字段为: http: //localhost :8000 /two/some/uri/ 这个指令: proxy_redirect http: //localhost :8000 /two/ http: //frontend/one/ ; 将Location字段重写为http: //frontend/one/some/uri/ 。 在代替的字段中可以不写服务器名: proxy_redirect http: //localhost :8000 /two/ /; 这样就使用服务器的基本名称和端口,即使它来自非80端口。 如果使用 "default" 参数,将根据location和proxy_pass参数的设置来决定。 例如下列两个配置等效: location /one/ { proxy_pass http: //upstream :port /two/ ; proxy_redirect default; } location /one/ { proxy_pass http: //upstream :port /two/ ; proxy_redirect http: //upstream :port /two/ /one/ ; } 在指令中可以使用一些变量: proxy_redirect http: //localhost :8000/ http: // $host:$server_port/; 这个指令有时可以重复: proxy_redirect default; proxy_redirect http: //localhost :8000/ /; proxy_redirect; /; 参数off将在这个字段中禁止所有的proxy_redirect指令: proxy_redirect off; proxy_redirect default; proxy_redirect http: //localhost :8000/ /; 利用这个指令可以为被代理服务器发出的相对重定向增加主机名: proxy_redirect / /; 将被代理服务器发出的重定向http协议的location改为https协议: proxy_redirect ~^http: // ([^:]+)(:\d+)?(.*)$ https: // $1$2$3; |
下面通过几个小实例来体验下proxy_redirect的使用效果:
==============================================================================
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 假设当前nginx的访问地址为http: //10 .10.10.9:8080,如果kevin-inc又需要302到10.10.10.9 /xxx 那么可以添加下redirect,将302的location改为http: //10 .10.10.9:8080 /xxx location /login { proxy_pass http: //kevin-inc/login ; proxy_redirect http: //10 .10.10.9/ http: //10 .10.10.9:8080/; } -------------------------------- host变量 如果不想写死ip地址,可以使用nginx的变量 location /login { proxy_pass http: //kevin-inc/login ; proxy_redirect http: // $host/ http: // $http_host/; } 其中host不带端口的,也就是nginx部署的主机ip,而$http_host是带端口的 |
==============================================================================
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | server { listen 80; server_name www.kevin.com; location / { proxy_pass http: //10 .0.8.40:9080; } } 这段配置一般情况下都正常,但偶尔会出错, 抓包发现服务器给客户端的跳转指令里加了端口号,如Location: http: //www .kevin.com:9080 /abc .html 。 因为nginx服务器侦听的是80端口,所以这样的URL给了客户端,必然会出错. 针对这种情况, 加一条proxy_redirect指令: proxy_redirect http: //www .kevin.com:9080/ / ,即把所有 "http://www.kevin.com:9080/" 的内容替换成 "/" 再发给客户端,就解决了。 server { listen 80; server_name www.kevin.com; proxy_redirect http: //www .kevin.com:9080/ /; location / { proxy_pass http: //10 .0.8.40:9080; } } |
==============================================================================
1 2 3 4 5 6 7 8 9 10 11 12 | 前端的Nginx负责把http: //www .kevin.com /grace/Server/ 开头的url反向代理到后端的http: //10 .0.8.40 /Server/ 上。 对于有完整的路径,如http: //www .kevin.com /grace/Server/ 的代理没有问题,Server对应后台服务器的一个目录。 但当访问http: //www .kevin.com /grace/Server 时,后端Nginx会发送一个301到/上,于是返回到前端后URL变成了http: //www .kevin.com /Server/ ,这个url显然不是我们想要的。 在Apache中有个ProxyPassReverse的参数,用来调整反向代理服务器发送的http应答头的url,可以解决这个问题。 在Nginx代理配置,可以使用proxy_redirect这个参数,它实现的功能和ProxyPassReverse类似,例如增加如下配置: location ^~ /grace { proxy_pass http: //10 .0.8.40/; proxy_redirect http: //www .kevin.com/ /grace/ ; } |
==============================================================================
如下启用了proxy_redirect配置(http->https),配置中就不需要"proxy_set_header Host $host;",即不需要"添加发往后端服务器的请求头"的配置了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | [root@external-lb01 vhosts] # cat 80-www.kevin.com.conf server { listen 80; server_name www.kevin.com kevin.com; access_log /data/nginx/logs/www .kevin.com-access.log main; error_log /data/nginx/logs/www .kevin.com-error.log; error_page 500 502 503 504 /50x .html; location = /50x .html { root html; } return 301 https: // $server_name$request_uri; } [root@external-lb01 ~] # cat /data/nginx/conf/vhosts/443-www.kevin.com.conf.bak upstream scf_cluster { ip_hash; server 192.168.10.20:9020; server 192.168.10.21:9020; } upstream portal_cluster { ip_hash; server 192.168.10.20:9040; server 192.168.10.21:9040; } upstream file_cluster{ ip_hash; server 192.168.10.20:9020; } upstream workflow_cluster{ ip_hash; server 192.168.10.20:9020; server 192.168.10.21:9020; } upstream batch_cluster{ server 192.168.10.20:9020; server 192.168.10.21:9020; } server { listen 443; server_name www.kevin.com kevin.com; ssl on; ssl_certificate /data/nginx/conf/ssl/kevin .cer; ssl_certificate_key /data/nginx/conf/ssl/kevin .key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE; ssl_prefer_server_ciphers on; access_log /data/nginx/logs/www .kevin.com-access.log main; error_log /data/nginx/logs/www .kevin.com-error.log; error_page 500 502 503 504 /50x .html; location = /50x .html { root html; } location /scf { proxy_pass http: //scf_cluster/scf ; proxy_redirect http: //scf_cluster/scf https: //www .kevin.com /scf ; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } location / { proxy_pass http: //portal_cluster/portal-pc/ ; proxy_redirect http: //portal_cluster/portal-pc/ https: //www .kevin.com/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } location /msdp-file { proxy_pass http: //file_cluster/msdp-file ; proxy_redirect http: //file_cluster/msdp-file https: //www .kevin.com /msdp-file ; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } location /upload { proxy_pass http: //file_cluster/upload ; proxy_redirect http: //file_cluster/upload https: //www .kevin.com /upload ; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } location /activiti-workflow-console { proxy_pass http: //workflow_cluster/activiti-workflow-console ; proxy_redirect http: //workflow_cluster/activiti-workflow-console https: //www .kevin.com /activiti-workflow-console ; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } location /batch-framework-web { proxy_pass http: //batch_cluster/batch-framework-web ; proxy_redirect http: //batch_cluster/batch-framework-web https: //www .kevin.com /batch-framework-web ; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } } |
===============================================================================
在看下nginx中非80端口的转发,注意:当端口是非80时,proxy_set_header项的$host后面一定要加上端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 如下,当http通过proxy_pass到非80端口的做法: [root@external-lb01 vhosts] # cat mobi.kevin.com.conf upstream mobi_cluster{ server 10.0.54.20:8080; } server { listen 80; server_name mobi.kevin.com; access_log /data/nginx/logs/mobi .kevin.com-access.log main; error_log /data/nginx/logs/mobi .kevin.com-error.log; location / { proxy_pass http: //mobi_cluster ; proxy_set_header Host $host; proxy_redirect http: //mobi_cluster/ http: //mobi .kevin.com/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } error_page 500 502 503 504 /50x .html; location = /50x .html { root html; } } |
=========================================================================
再看一个匹配上下文的代理配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | [root@uatinner-lb01 vhosts] # cat /opt/uatbob-vfc.kevin.com.conf server { listen 443; server_name uatbob-vfc.kevin.com; ssl on; ssl_certificate /data/nginx/conf/ssl/ssl .kevin.com.crt; ssl_certificate_key /data/nginx/conf/ssl/ssl .kevin.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE; ssl_prefer_server_ciphers on; access_log /data/nginx/logs/uatbob-vfc .kevin.com-access.log main; error_log /data/nginx/logs/uatbob-vfc .kevin.com-error.log; location /devxcd/ { proxy_pass http: //172 .16.50.16:50002/; proxy_redirect off ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; #proxy_cache mycache; #proxy_cache_valid 200 302 1h; #proxy_cache_valid 301 1d; #proxy_cache_valid any 1m; } location /fvtxcd/ { proxy_pass http: //172 .16.50.75:50002/; proxy_redirect off ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; #proxy_cache mycache; #proxy_cache_valid 200 302 1h; #proxy_cache_valid 301 1d; #proxy_cache_valid any 1m; } location /uatxcd/ { proxy_pass http: //172 .16.50.184:50002/; proxy_redirect off ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; #proxy_cache mycache; #proxy_cache_valid 200 302 1h; #proxy_cache_valid 301 1d; #proxy_cache_valid any 1m; } location /devxcd/xcdcomment/ { proxy_pass http: //172 .16.50.73:9997/; } location /fvtxcd/xcdcomment/ { proxy_pass http: //172 .16.50.73 /9997/ ; } location /uatxcd/xcdcomment/ { proxy_pass http: //172 .16.50.73 /9997/ ; } } 上面配置匹配 /devxcd/xcdcomment/ , /fvtxcd/xcdcomment/ , /uatxcd/xcdcomment/ 的上下文代理后, 访问: https: //uatbob-vfc .kevin.com /devxcd/xcdcomment/images/example_doorPlate .jpg 访问正常打开 https: //uatbob-vfc .kevin.com /fvtxcd/xcdcomment/images/example_doorPlate .jpg 访问出现404 https: //uatbob-vfc .kevin.com /uatxcd/xcdcomment/images/example_doorPlate .jpg 访问出现404 解决: 添加proxy_redirect配置项 修改后的配置 [root@uatinner-lb01 vhosts] # cat uatbob-vfc.kevin.com.conf server { listen 443; server_name uatbob-vfc.kevin.com; ssl on; ssl_certificate /data/nginx/conf/ssl/ssl .kevin.com.crt; ssl_certificate_key /data/nginx/conf/ssl/ssl .kevin.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE; ssl_prefer_server_ciphers on; access_log /data/nginx/logs/uatbob-vfc .kevin.com-access.log main; error_log /data/nginx/logs/uatbob-vfc .kevin.com-error.log; location /devxcd/ { proxy_pass http: //172 .16.50.16:50002/; proxy_redirect off ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; #proxy_cache mycache; #proxy_cache_valid 200 302 1h; #proxy_cache_valid 301 1d; #proxy_cache_valid any 1m; } location /fvtxcd/ { proxy_pass http: //172 .16.50.75:50002/; proxy_redirect off ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; #proxy_cache mycache; #proxy_cache_valid 200 302 1h; #proxy_cache_valid 301 1d; #proxy_cache_valid any 1m; } location /uatxcd/ { proxy_pass http: //172 .16.50.184:50002/; proxy_redirect off ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; #proxy_cache mycache; #proxy_cache_valid 200 302 1h; #proxy_cache_valid 301 1d; #proxy_cache_valid any 1m; } location /devxcd/xcdcomment/ { proxy_pass http: //172 .16.50.73:9997/; proxy_redirect http: //http : //172 .16.50.73:9997/ https: //uatbob-vfc .kevin.com /devxcd/xcdcomment/ ; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } location /fvtxcd/xcdcomment/ { proxy_pass http: //172 .16.50.73:9997/; proxy_redirect http: //http : //172 .16.50.73:9997/ https: //uatbob-vfc .kevin.com /fvtxcd/xcdcomment/ ; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } location /uatxcd/xcdcomment/ { proxy_pass http: //172 .16.50.73:9997/; proxy_redirect http: //http : //172 .16.50.73:9997/ https: //uatbob-vfc .kevin.com /uatxcd/xcdcomment/ ; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 600; proxy_buffer_size 256k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404; proxy_max_temp_file_size 128m; } } 修改后, 访问: https: //uatbob-vfc .kevin.com /devxcd/xcdcomment/images/example_doorPlate .jpg 访问正常打开 https: //uatbob-vfc .kevin.com /fvtxcd/xcdcomment/images/example_doorPlate .jpg 访问正常打开 https: //uatbob-vfc .kevin.com /uatxcd/xcdcomment/images/example_doorPlate .jpg 访问正常打开 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2016-12-20 Git管理项目实例说明-记录和跟踪项目
2016-12-20 Maven私服Nexus3.x环境构建操作记录