HTTP学习笔记之三——Proxy代理服务器

本文深入解析代理服务器与反向代理缓冲服务器的类型、工作原理及应用场景,包括标准代理、透明代理与反向代理的区别,以及它们在缓存、负载均衡、安全与加密等领域的应用。此外,阐述了代理服务器在网络部署中的访问控制、防火墙、内容缓冲等功能,并解释了其作为filewall的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


出于安全考虑,局域网内的机器访问访问墙外的网站借助于代理服务器进行,如果把局域网外Internet想象成一个巨大的资源库,局域网内的用户要访问这个库里的资源必须统一通过代理服务器进行。反过来,如果局域网向Internet提供资源,让Internet上的用户访问局域网内的资源也可以设置成一个代理服务器,只不过与我们常用的代理服务器方向正好相反,所以叫反向代理(Reverse Proxy)。

1、代理可分为三种: 标准的代理缓冲服务器、透明代理缓冲服务器、反向代理缓冲服务器
(1)标准的代理缓冲服务器
  这种方式需要在Client浏览器配置中指明Proxy的IP地址和端口号。浏览器每次都把请求送给Proxy处理。Proxy可以有缓存的功能:它根据请求确定是否连接到Remote Origin Server获取数据,如果在本地缓冲区有目标数据(cache hit),则直接将缓存数据传给用户即可,如果没有的话则先取回数据(cache miss),先在本地保存一份缓冲,然后将数据发给客户端浏览器。
(2)透明代理缓冲服务器
  透明代理缓冲服务器和标准代理服务器的功能完全相同,但是代理操作对客户端的浏览器是透明的(即不需指明代理服务器的IP和端口号)。透明代理服务器阻断网络通信,并且过滤出访问外部的HTTP(80端口)流量。如果客户端的请求在本地有缓冲则将缓冲的数据直接发给用户,如果在本地没有缓冲则向远程web服务器发出请求,其余操作和标准的代理服务器完全相同。对于Linux操作系统来说,透明代理使用Iptables或者Ipchains实现。因为不需要对浏览器作任何设置,所以透明代理对于ISP(Internet服务器提供商)特别有用。
(3)反向代理缓冲服务器(surrogate)
  反向代理是和前两种代理完全不同的一种代理服务,使用它可以降低原始web服务器的负载。反向代理服务器承担了对原始web服务器的静态页面的请求,防止原始服务器过载。它位于本地web服务器和Internet之间,处理所有对web服务器的请求,组织了web服务器和Internet的直接通信。如果互联网用户请求的页面在代理服务器上有缓冲的话,代理服务器直接将缓冲内容发送给用户;如果没有缓冲,则先向web服务器发出请求,取回数据并在本地缓存后再发送给用户。这种方式通过降低了向web服务器的请求数,从而降低了web服务器的负载。

2、反向代理有两种用法:
(1)一种是为多个网站的Web服务器提供代理,这些网站的域名都指向surrogate,对这些网站的请求全都发给了surrogate,由surrogate转发HTTP请求给相应网站的origin server。
(2)一种是为一个网站的Web服务器集群提供代理,surrogate作为负载均衡器决定具体哪个origin server接收请求。

surrogate总是位于Web服务器的前端,Internet上的用户对Web服务器的连接要先经过surrogate,然后由surrogate决定哪个Web服务器处理用户请求,并将请求路由给相应的Web服务器。对静态内容可以在反向代理上缓存,这样就不用再向Web服务器路由了。

3、除了缓存和负载均衡,surrogate还能提供如下功能:
(1)安全:反向代理隔离了用户和Web服务器,用户很难针对特定的服务器发动攻击;
(2)数据加密/SSL加速: 某些Web服务器可能不具有SSL加密功能,但是具有加密功能的反向代理服务器可以为Web服务器提供数据加密,而且装备了SSL加速硬件的反向代理服务器还能为Web应用提供了高速的加密通道;
(3)压缩:代理服务器能压缩经过的数据以节省带宽


1、Proxy介于Client和Server中间,它同时扮演了Client和Server的双重角色:

对于Client而言,Proxy就像一个Server,Proxy处理Client的请求,并将Server的响应转发给Client;

对于Server而言,Proxy就像一个Client,Proxy转发Client的请求给Server,并接收Server返回的响应;


2、Proxy可以分为public proxy和private proxy:

public proxy可以同时为多个client提供服务,考虑到不同client可能会发出相同的request(例如100个用户同时访问新浪网),可以在proxy上caching这些访问率非常高的网页,从而大大提高效率;

private proxy仅为一个client提供服务,通常这样的私有代理是绑定在client上的,为该client提供一些扩展服务。


3、Proxy与gateway的区别:

proxy只能连接使用相同协议的应用程序;而gateway可以连接使用不同协议的应用程序,更像一个协议翻译者(protocol converter);

(但是现在这种区别已经模糊了,一些代理也具有网关的功能)



4、proxy可以作为local network的filewall,它是通往Internet的唯一出口。所有用户对公网的访问都要经过proxy,从而实现一些访问控制的过滤机制,并保护该局域网免受外网的入侵。下面图示了proxy的几类主要功能:


(1)proxy的访问控制功能(access control):



(2)proxy作为防火墙(firewall):



(3)proxy作为内容缓冲(cache):


(4)反向代理(surrogate),位于Internet和Web Server之间,可以分担Server的负载:



(5)content router




5、proxy在网络中的部署:



6、proxy怎么得到流量:

(1)在客户端浏览器中进行配置,让浏览器直接访问代理服务器而非源服务器。

(2)利用router, gateway的拦截和路由功能,将客户端流量引导至proxy,这种技术的优点是客户端不需要做任何配置。

(3)修改DNS映射关系,例如将surrogate配置为origin server的IP和hostname,这样来自客户端的流量将被引导至surrogate中。

(4)修改origin server,将其接收到的请求重定向到proxy中。






### C++ gRPC 学习教程和示例代码 #### 一、环境搭建 为了能够顺利运行C++中的gRPC程序,需要先完成开发环境的配置。这通常涉及到安装必要的依赖库以及设置编译工具链。具体来说,可以按照官方文档指导来准备所需的软件包,比如Protocol Buffers编译器`protoc`及其对应的C++插件,还有gRPC核心库等[^1]。 ```bash sudo apt-get install build-essential autoconf libtool pkg-config git clone https://github.com/protocolbuffers/protobuf.git cd protobuf ./autogen.sh && ./configure && make -j$(nproc) && sudo make install ``` 对于gRPC本身,则可以通过如下命令获取并构建: ```bash git clone --recurse-submodules -b v1.48.x https://github.com/grpc/grpc cd grpc mkdir -p cmake/build && cd cmake/build cmake ../.. make -j$(nproc) sudo make install ``` #### 二、创建Protobuf文件 接下来就是定义服务接口,在`.proto`文件里描述消息结构和服务方法。这里给出一个简单的例子——HelloWorld服务,其中包含了一个名为SayHello的方法用于接收请求并向客户端返回响应信息。 ```protobuf syntax = "proto3"; option cc_enable_arenas = true; package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; } ``` 保存上述内容到`helloworld.proto`之后,利用之前提到过的`protoc`命令行工具将其转换成相应的头文件与源码文件以便后续使用。 #### 三、编写服务器端逻辑 基于前面所生成的服务类模板,现在可以在项目中实现具体的业务处理函数了。下面展示的是如何继承自动生成出来的基类,并重写虚函数以提供实际功能的部分代码片段。 ```cpp #include <iostream> #include "helloworld.grpc.pb.h" using namespace std; using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::Status; using helloworld::Greeter; using helloworld::HelloReply; using helloworld::HelloRequest; class GreeterServiceImpl final : public Greeter::Service { public: Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override { string prefix("Hello "); reply->set_message(prefix + request->name()); return Status::OK; } }; ``` 这段代码实现了当接收到客户端发起的调用时会执行的操作:拼接字符串形成回复文本并通过参数传递给对方。 #### 四、启动监听进程 有了完整的协议声明加上对应的功能模块后就可以着手建立网络连接等待远端访问啦! ```cpp void RunServer() { string server_address("0.0.0.0:50051"); GreeterServiceImpl service; ServerBuilder builder; // Listen on the given address without any authentication mechanism. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); // Register "service" as the instance through which we'll communicate with // clients. In this case it corresponds to an *synchronous* service. builder.RegisterService(&service); // Finally assemble the server. unique_ptr<Server> server(builder.BuildAndStart()); cout << "Server listening on " << server_address << endl; // Wait for the server to shutdown. Note that some other thread must be // responsible for shutting down the server for this call to ever return. server->Wait(); } ``` 此部分负责初始化HTTP/2传输层设施并将指定地址开放出去供外界联系;同时注册好先前定义好的处理器对象使得每次有新链接进来都能找到合适的地方去解析数据流进而触发相应动作。 #### 五、客户端编程指南 最后一步自然是要让应用程序具备主动出击的能力咯~即构造出能向远程主机发出请求的消息体格式化为wire format再经由socket发送过去得到回应为止的过程。 ```cpp void RunClient() { string target_str("localhost:50051"); // Instantiate the client. It requires a channel, out of which the actual RPCs // are created. This channel models a connection to an endpoint specified by // the argument; you may provide extra arguments to indicate credentials, // compression Level etc. shared_ptr<Channel> channel = CreateChannel(target_str, InsecureChannelCredentials()); // Stub acts like a proxy object representing remote side entity. unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel)); // Data we are sending to the server. HelloRequest request; request.set_name("you"); // Container for the data we expect from the server. HelloReply reply; // Context for the client. It could be used to convey extra information to // the server and/or tweak certain RPC behaviors. ClientContext context; // The actual RPC. Status status = stub->SayHello(&context, request, &reply); // Act upon its status. if (status.ok()) { cout << "Greeter received: " << reply.message() << endl; } else { cerr << status.error_code() << ": " << status.error_message() << endl; } } ``` 以上便是整个流程的大致介绍,当然这只是冰山一角而已,更多高级特性和最佳实践还需要读者朋友们自行探索学习哦~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值