news 2026/9/30 7:11:00

gRPC微服务搭建(学习阶段3:数据服务系统)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gRPC微服务搭建(学习阶段3:数据服务系统)

这篇播客基于 Python gRPC 实现的客户端与服务端通信:

  1. 首先模拟一个简单的数据服务系统,客户端通过登录接口进行身份验证;在服务端验证用户名和密码后生成 Token
  2. 服务端接收到请求后,会通过gRPC拦截器统一完成日志记录和Token鉴权。鉴权成功后,服务端根据客户端传入的开始日期、结束日期和字段列表,使用pandas动态生成一份随机DataFrame数据,并将数据返回给客户端。

服务端代码

这里服务端注册两个主要的函数:

  1. auth.Auth服务的login函数,用于做权限校验
  2. data.Data服务的GetData函数,用于获取数据,在这段代码中是基于用户传入的参数生成一个模拟的数据
importjsonimportloggingimportsecretsfromconcurrentimportfuturesimportgrpcimportpandasaspd logging.basicConfig(level=logging.INFO,format="%(asctime)s [%(levelname)s] %(message)s",)logger=logging.getLogger(__name__)TOKENS={}deflogin(request,_context):"""登录成功后生成并保存 Token。"""username=request.get("username")password=request.get("password")logger.info("收到登录请求:username=%s",username)ifusername!="admin"orpassword!="123456":logger.warning("登录失败:username=%s",username)return{"success":False,"message":"用户名或密码错误"}token=secrets.token_hex(16)TOKENS[token]=username logger.info("登录成功:username=%s",username)return{"success":True,"token":token,"message":"登录成功"}defget_data(request,_context):"""根据日期范围和字段生成一份随机 DataFrame 数据。"""start_date=request.get("start_date")end_date=request.get("end_date")fields=request.get("fields",[])ifnotstart_dateornotend_dateornotfields:return{"success":False,"message":"start_date、end_date、fields 不能为空"}try:dates=pd.date_range(start=start_date,end=end_date,freq="D")exceptValueError:return{"success":False,"message":"日期格式应为 YYYY-MM-DD"}dataframe=pd.DataFrame({"date":dates.strftime("%Y-%m-%d"),**{field:pd.Series(secrets.randbelow(10000)/100for_indates)forfieldinfields},})return{"success":True,"data":dataframe.to_dict(orient="records"),"message":"数据获取成功",}defjson_handler(function):"""统一处理 Python 字典和 JSON 字节之间的转换。"""returngrpc.unary_unary_rpc_method_handler(function,request_deserializer=lambdadata:json.loads(data.decode("utf-8")),response_serializer=lambdadata:json.dumps(data,ensure_ascii=False).encode("utf-8"),)classLoggingInterceptor(grpc.ServerInterceptor):"""记录每次 gRPC 请求。"""defintercept_service(self,continuation,handler_call_details):method=handler_call_details.method logger.info("收到 gRPC 请求:method=%s",method)handler=continuation(handler_call_details)ifhandlerisNone:logger.warning("找不到 gRPC 方法:method=%s",method)returnhandlerclassAuthInterceptor(grpc.ServerInterceptor):"""在业务函数执行前检查 Token。"""defintercept_service(self,continuation,handler_call_details):method=handler_call_details.method handler=continuation(handler_call_details)ifhandlerisNone:returnNoneifmethod=="/auth.Auth/Login":returnhandlerdefcheck_token(request,context):token=request.get("token")iftokennotinTOKENS:logger.warning("鉴权失败:method=%s",method)context.abort(grpc.StatusCode.UNAUTHENTICATED,"请先登录")logger.info("鉴权成功:method=%s, user=%s",method,TOKENS[token])returnhandler.unary_unary(request,context)returnhandler._replace(unary_unary=check_token)defcreate_server(address="[::]:50051",max_workers=4):"""创建并配置 gRPC 服务。"""grpc_server=grpc.server(futures.ThreadPoolExecutor(max_workers=max_workers),interceptors=[LoggingInterceptor(),AuthInterceptor()],)grpc_server.add_generic_rpc_handlers((grpc.method_handlers_generic_handler("auth.Auth",{"Login":json_handler(login)},),grpc.method_handlers_generic_handler("data.Data",{"GetData":json_handler(get_data)},),))grpc_server.add_insecure_port(address)returngrpc_serverdefserve():"""启动 gRPC 服务并持续等待请求。"""address="[::]:50051"grpc_server=create_server(address)grpc_server.start()logger.info("gRPC 服务已启动:address=%s",address)grpc_server.wait_for_termination()if__name__=="__main__":serve()

客户端代码

客户端是极简代码,直接登录,获取token后直接获取数据即可

importjsonimportgrpc# 把 Python 字典转换成 JSON 发送,并把 JSON 响应转换回来。defcall(channel,method,data):request=channel.unary_unary(method,request_serializer=lambdavalue:json.dumps(value).encode("utf-8"),response_deserializer=lambdavalue:json.loads(value.decode("utf-8")),)returnrequest(data)# 连接服务端。withgrpc.insecure_channel("127.0.0.1:50051")aschannel:# 1. 登录,获取 Token。login_result=call(channel,"/auth.Auth/Login",{"username":"admin","password":"123456"},)print(login_result["message"])# 2. 使用 Token 查询指定日期和字段的数据。result=call(channel,"/data.Data/GetData",{"token":login_result["token"],"start_date":"2025-01-01","end_date":"2025-01-05","fields":["open","close","volume"],},)# 3. 打印服务端返回的数据。print(result["data"])
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 7:10:51

存算一体与新型存储的嵌入式落地:打破内存墙的工程路径

摘要:存算一体正在从学术研究走向嵌入式落地。SK海力士联合研发的忆阻器AI芯片采用嵌入式RISC-V处理器调度任务,理论峰值约2.54 TOPS。elexcon2026将新型存储技术列为六大核心方向之一。本文从技术路线、工程特性和应用场景三个维度,分析存算…

作者头像 李华
网站建设 2026/9/30 7:10:32

电动车V2G有望能赚钱了?V2G上海居民区实测落地

TL;DR:2025年,上海落地国内最具代表性的居民区V2G规模化试点:联联睿科一年安装1641台私人双向充电桩、731名用户参与,全年累计向电网放电超2万度,部分车主电费账单已经"转负"。针对"放电伤电池"这…

作者头像 李华
网站建设 2026/9/30 7:10:26

蓝牙芯片驱动开发-第7章第1题-芯片睡眠模式的分类标准有哪些

蓝牙面试题解析:芯片睡眠模式的分类标准有哪些? 难度:⭐⭐⭐ 中等 | 场景:社招一面/二面、低功耗开发 | 高频:🔥🔥🔥🔥 标准答案 芯片睡眠模式依据 功耗等级、唤醒时间、保留状态 三个维度分类,通常分为深睡、浅睡、待机三个级别: ① 三种睡眠模式对比 模式 功…

作者头像 李华
网站建设 2026/9/30 7:07:52

二十九、企业级文档问答系统:从零构建一个完整的生产级项目

企业级文档问答系统:从零构建一个完整的生产级项目 📚 专栏导航:这是《LangChain 30篇精讲》的第 29 篇,模块七「项目实战与总结」的开篇。前 28 篇,我们从模型接口一路学到生产部署,知识装了一脑袋。但知识散落各处,是时候把它们串联成一个真实项目了。 写在前面:这次…

作者头像 李华
网站建设 2026/9/30 7:06:27

一文讲透:企业财税合规的三大核心维度与落地思路

在很多中小微企业的经营认知里,“财税合规” 常常是一个被动的、事后的概念:平时忙着拓业务、抓营收,账务能凑就凑、发票能省则省,总觉得 “没被查到就不算问题”;直到遇到税务稽查、股权变更、融资尽调、资质申报时&a…

作者头像 李华
网站建设 2026/9/30 7:03:28

仿FinalShell免费版更适合多台同时运维工具

仿FinalShell免费版更适合多台同时运维 MuySSH 是一款 Windows 桌面 SSH 客户端,用来连接远程 Linux 主机。 打开连接后可以在终端里执行命令,用 SFTP 管理文件,并从命令面板填入常用系统命令。 连接、密钥和代理配置保存在本机,并…

作者头像 李华