昆明免费网站建设江宁建设局网站

张小明 2026/3/12 11:44:20
昆明免费网站建设,江宁建设局网站,上海出口贸易公司,佛山网约车驾驶员资格证网上报名#x1f680; 前言#xff1a;为什么是 gRPC#xff1f; 在微服务架构中#xff0c;RESTful API 虽然通用#xff0c;但在内部服务调用场景下#xff0c;它的效率成为了瓶颈#xff08;JSON 序列化慢、HTTP/1.1 头部冗余#xff09;。 gRPC 基于 HTTP/2 和 Protobuf 前言为什么是 gRPC在微服务架构中RESTful API 虽然通用但在内部服务调用场景下它的效率成为了瓶颈JSON 序列化慢、HTTP/1.1 头部冗余。gRPC基于HTTP/2和Protobuf提供了二进制传输、多路复用、双向流等特性性能比 REST 高出一个数量级。本文将带你从 0 构建一个包含普通调用和流式调用的订单服务并手写拦截器和单元测试。️ 第一阶段环境搭建与 IDL 定义gRPC 的核心是Contract First契约优先。我们需要先写.proto文件。1. Maven 依赖与插件这是最容易劝退新手的环节。你需要配置protobuf-maven-plugin来自动生成 Java 代码。dependenciesdependencygroupIdio.grpc/groupIdartifactIdgrpc-netty-shaded/artifactIdversion1.54.0/version/dependencydependencygroupIdio.grpc/groupIdartifactIdgrpc-protobuf/artifactIdversion1.54.0/version/dependencydependencygroupIdio.grpc/groupIdartifactIdgrpc-stub/artifactIdversion1.54.0/version/dependencydependencygroupIdorg.apache.tomcat/groupIdartifactIdannotations-api/artifactIdversion6.0.53/versionscopeprovided/scope/dependency/dependenciesbuildextensionsextensiongroupIdkr.motd.maven/groupIdartifactIdos-maven-plugin/artifactIdversion1.7.1/version/extension/extensionspluginsplugingroupIdorg.xolstice.maven.plugins/groupIdartifactIdprotobuf-maven-plugin/artifactIdversion0.6.1/versionconfigurationprotocArtifactcom.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier}/protocArtifactpluginIdgrpc-java/pluginIdpluginArtifactio.grpc:protoc-gen-grpc-java:1.54.0:exe:${os.detected.classifier}/pluginArtifact/configurationexecutionsexecutiongoalsgoalcompile/goalgoalcompile-custom/goal/goals/execution/executions/plugin/plugins/build2. 定义order.proto我们在src/main/proto下创建文件。为了演示深度我们定义两个接口一个简单调用一个服务端流式调用Server Streaming。syntax proto3; package com.example.grpc; option java_multiple_files true; option java_package com.example.grpc.lib; option java_outer_classname OrderProto; service OrderService { // 1. 简单一元调用根据 ID 查订单 rpc GetOrder (OrderRequest) returns (OrderResponse); // 2. 服务端流式调用实时获取订单状态流 rpc WatchOrderStatus (OrderRequest) returns (stream OrderStatus); } message OrderRequest { int32 order_id 1; } message OrderResponse { int32 order_id 1; string product_name 2; double price 3; } message OrderStatus { string status 1; string timestamp 2; }执行mvn compile你会发现在target/generated-sources下生成了 Java 代码。 第二阶段服务端实现 (Server)服务端需要继承生成的ImplBase类。publicclassOrderServiceImplextendsOrderServiceGrpc.OrderServiceImplBase{// 1. 实现简单调用OverridepublicvoidgetOrder(OrderRequestrequest,StreamObserverOrderResponseresponseObserver){System.out.println(收到查询请求 ID: request.getOrderId());// 模拟数据库查询OrderResponseresponseOrderResponse.newBuilder().setOrderId(request.getOrderId()).setProductName(MacBook Pro M3).setPrice(12999.00).build();// 返回数据responseObserver.onNext(response);// 结束调用 (必须调用否则客户端会一直等待)responseObserver.onCompleted();}// 2. 实现服务端流式调用 (Server Streaming)OverridepublicvoidwatchOrderStatus(OrderRequestrequest,StreamObserverOrderStatusresponseObserver){// 模拟订单状态变化每隔1秒推送一次String[]statuses{已下单,支付成功,仓库配货,已发货,派送中};for(Stringstatus:statuses){try{Thread.sleep(500);}catch(InterruptedExceptione){}OrderStatusorderStatusOrderStatus.newBuilder().setStatus(status).setTimestamp(System.currentTimeMillis()).build();// 推送一条流数据responseObserver.onNext(orderStatus);}responseObserver.onCompleted();}}启动 ServerpublicclassGrpcServer{publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{// 添加拦截器 (后面讲)ServerserverServerBuilder.forPort(9090).addService(ServerInterceptors.intercept(newOrderServiceImpl(),newAuthInterceptor())).build();server.start();System.out.println(gRPC Server started on port 9090);server.awaitTermination();}} 第三阶段客户端调用 (Client)客户端通常使用Stub (存根)来调用。publicclassGrpcClient{publicstaticvoidmain(String[]args){// 1. 创建通道 (Connection)ManagedChannelchannelManagedChannelBuilder.forAddress(localhost,9090).usePlaintext()// 测试环境使用明文传输.build();// 2. 创建 Stub// BlockingStub: 同步阻塞调用OrderServiceGrpc.OrderServiceBlockingStubblockingStubOrderServiceGrpc.newBlockingStub(channel);// 3. 简单调用OrderResponseresponseblockingStub.getOrder(OrderRequest.newBuilder().setOrderId(1001).build());System.out.println(查询结果: response.getProductName());// 4. 流式调用 (需要用 Iterator)IteratorOrderStatusstatusIteratorblockingStub.watchOrderStatus(OrderRequest.newBuilder().setOrderId(1001).build());while(statusIterator.hasNext()){OrderStatusstatusstatusIterator.next();System.out.println(当前状态: status.getStatus());}channel.shutdown();}}️ 第四阶段进阶 —— 拦截器 (Interceptor)在生产环境中我们不可能裸奔。我们需要拦截器来做Auth 鉴权或日志记录。gRPC 使用Metadata(类似 HTTP Header) 来传递元数据。服务端拦截器验证 TokenpublicclassAuthInterceptorimplementsServerInterceptor{privatestaticfinalMetadata.KeyStringTOKEN_KEYMetadata.Key.of(auth-token,Metadata.ASCII_STRING_MARSHALLER);OverridepublicReqT,RespTServerCall.ListenerReqTinterceptCall(ServerCallReqT,RespTcall,Metadataheaders,ServerCallHandlerReqT,RespTnext){// 获取客户端传来的 TokenStringtokenheaders.get(TOKEN_KEY);if(secret-123.equals(token)){// 验证通过放行returnnext.startCall(call,headers);}else{// 验证失败直接关闭连接call.close(Status.UNAUTHENTICATED.withDescription(Token无效),headers);returnnewServerCall.Listener(){};}}}客户端发送 Token// 客户端需要自定义一个 CallCredentials 或者使用 ClientInterceptor// 这里使用 MetadataUtils 快速注入OrderServiceGrpc.OrderServiceBlockingStubstubOrderServiceGrpc.newBlockingStub(channel);MetadatametanewMetadata();meta.put(Metadata.Key.of(auth-token,Metadata.ASCII_STRING_MARSHALLER),secret-123);// 将 Metadata 附着在 Stub 上stubMetadataUtils.attachHeaders(stub,meta); 第五阶段单元测试 (Test)这是区分新手和高手的地方。不要启动真实的 Server 去测太慢且依赖网络。gRPC 提供了grpc-testing库支持InProcessServer (进程内服务器)速度极快。引入依赖dependencygroupIdio.grpc/groupIdartifactIdgrpc-testing/artifactIdversion1.54.0/versionscopetest/scope/dependency编写 JUnit 5 测试用例publicclassOrderServiceTest{privateServerinProcessServer;privateManagedChannelinProcessChannel;privateOrderServiceGrpc.OrderServiceBlockingStubblockingStub;BeforeEachpublicvoidsetUp()throwsException{// 生成唯一的服务器名称StringserverNameInProcessServerBuilder.generateName();// 1. 启动进程内服务器 (绑定我们实现的 Service)inProcessServerInProcessServerBuilder.forName(serverName).directExecutor()// 不使用线程池直接在当前线程执行方便测试.addService(newOrderServiceImpl()).build().start();// 2. 创建连接到该服务器的 ChannelinProcessChannelInProcessChannelBuilder.forName(serverName).directExecutor().build();blockingStubOrderServiceGrpc.newBlockingStub(inProcessChannel);}AfterEachpublicvoidtearDown(){inProcessChannel.shutdown();inProcessServer.shutdown();}TestpublicvoidtestGetOrder(){// givenOrderRequestrequestOrderRequest.newBuilder().setOrderId(888).build();// whenOrderResponseresponseblockingStub.getOrder(request);// thenassertEquals(888,response.getOrderId());assertEquals(MacBook Pro M3,response.getProductName());}} 总结通过这篇文章你掌握了 gRPC 开发的完整闭环IDL 定义proto文件是核心契约。流式通信用StreamObserver实现实时推送。拦截器用Metadata实现 Token 鉴权。InProcess 测试不依赖网络的极速单元测试。gRPC 不仅仅是高性能更是规范化微服务调用的利器。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

网站开发项目经理软件工程 宣传网站建设

目录已开发项目效果实现截图开发技术系统开发工具:核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式&…

张小明 2026/3/10 16:22:24 网站建设

企业为什么需要搭建一个网站化妆品网站建设方案项目书

继上一篇GPIO输入输出的内容补充 文章目录GPIO输入GPIO输出寄存器GPIO输入 输入浮空、输入上拉、输入下拉 如图为官方手册中I/O端口位的输入配置。 我们可以看到,在这三种输入模式下,输出部分被断开无法使用。 模拟输入 模拟输入模式下,和…

张小明 2026/3/10 16:22:26 网站建设

苏州网站设计都选苏州聚尚网络杭州小周seo

Linly-Talker能否用于法庭模拟教学数字人构建? 在法学院的模拟法庭教室里,学生们围坐一圈,面对屏幕上的“法官”陈述辩护意见。这位法官不仅语气威严、逻辑严密,还能即时回应学生的质疑,甚至根据庭审规则指出程序漏洞—…

张小明 2026/3/10 16:22:28 网站建设

安徽省建设厅网站温州seo排名

你是否曾经面对Windows资源管理器里一片空白的HEIC文件图标感到困惑?这些来自iPhone的高效图像格式文件,在Windows系统中就像隐形人一样存在。今天,让我们一起打破这个技术壁垒,让每个HEIC文件都能在文件管理器中"现身"…

张小明 2026/3/10 16:26:35 网站建设

建设银行个人网银网站咨询公司成本费用包括哪些内容

gawk 安装与 GNU 通用公共许可证解读 1. gawk 安装与相关信息 gawk 是一款功能强大的工具,其发行版本可从 GNU 项目的主分发站点 ftp.gnu.org 获取。以下是标准的构建步骤: wget http://ftp.gnu.org/gnu/gawk/gawk-4.1.2.tar.gz tar -xvpzf gawk-4.1.2.tar.gz cd gawk-4.…

张小明 2026/3/10 16:26:37 网站建设

义乌 外贸网站 开发个人网站空间怎么做

简介 在前端开发中,px 和 em 是最常见的两种长度单位。理解它们的语义与使用场景,有助于实现更可访问、响应性更好的界面。什么是 px? - px(像素)是绝对单位,表示屏幕上的一个逻辑像素点(与…

张小明 2026/3/10 16:26:38 网站建设