Nacos 配置中心全操作

配置中心:从接入到动态刷新 📖 前置阅读:本文假设读者已掌握 Nacos 的基本概念和 @RefreshScope。如果还不熟悉,建议先阅读 Nacos 核心概念与快速上手。 一、⚡ 数据库密码改了——5 个服务 15 个实例要一个个改? 先来看看没有配置中心时的情况: 场景:MySQL 主库切换——数据库地址从 mysql-master-1 变成 mysql-master-2 没有配置中心: ① 改 5 个服务的 application.yml——每个服务改一次 ② 重新打包/重启 15 个实例——顺序不能错(先启 DB 相关的) ③ 改到一半发现有个服务漏了——生产故障 耗时:30 分钟 + 心跳加速 有了 Nacos 配置中心: ① 在 Nacos Dashboard 改一个配置——mysql.host ② 点发布——15 个实例自动收到推送 ③ @RefreshScope 的 Bean 自动重建——新配置生效 耗时:1 分钟 + 淡定 配置中心的价值就是一句话:改一次——推所有——不用重启。 二、🧩 配置的三级组织——shared-configs / extension-configs / 本地 Nacos 配置有三层——从最共享到最专属: shared-configs(共享配置) ← 所有服务通用的配置 ↓ 可以被覆盖 extension-configs(扩展配置) ← 一组服务共享的配置 ↓ 可以被覆盖 ${spring.application.name}-${profile}.${ext}(服务专属配置) ← 每个服务自己的配置 ↓ 兜底 application.yml(本地配置) ← 开发环境兜底——生产通常不放关键配置 2.1 三层配置在 yml 中怎么配 # bootstrap.yml(早于 application.yml 加载——连 Nacos 必须放这里) spring: application: name: order-service profiles: active: dev cloud: nacos: config: server-addr: localhost:8848 namespace: dev group: DEFAULT_GROUP file-extension: yaml # ① shared-configs——所有服务共享的公共配置 shared-configs: - data-id: common-mysql.yaml # 数据库公共配置——所有服务共用一个 DB 集群 group: DEFAULT_GROUP refresh: true # 允许动态刷新 - data-id: common-redis.yaml # Redis 公共配置 group: DEFAULT_GROUP refresh: true - data-id: common-log.yaml # 日志公共配置 group: DEFAULT_GROUP refresh: false # 日志配置不动态刷新——改日志级别才需要 # ② extension-configs——当前服务专属——比 shared 优先级高 extension-configs: - data-id: order-service-custom.yaml group: DEFAULT_GROUP refresh: true 2.2 Nacos Dashboard 中创建公共配置 Nacos Dashboard → 配置管理 → 配置列表 → 新建配置 ① common-mysql.yaml (DEFAULT_GROUP): spring: datasource: url: jdbc:mysql://mysql-master:3306/ username: app_user password: ${MYSQL_PASSWORD} # ← 密码用环境变量——不写在配置中心 hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 3000 ② common-redis.yaml (DEFAULT_GROUP): spring: redis: host: redis-cluster.internal port: 6379 lettuce: pool: max-active: 20 max-idle: 10 ③ order-service-dev.yaml (DEFAULT_GROUP): # 订单服务专属配置——覆盖或扩展公共配置 spring: datasource: url: jdbc:mysql://mysql-master:3306/order_db?useSSL=false # 覆盖——订单库 hikari: maximum-pool-size: 50 # 覆盖公共配置——订单服务连接池要大一些 app: order: max-items-per-order: 50 payment-timeout-seconds: 1800 2.3 配置加载的优先级——哪个生效? 当同一个配置在多个地方出现时——后加载的覆盖先加载的: ...

十二月 15, 2022 · 5 分钟 · 953 字 · yaomingye

OpenFeign 生产实战——Nacos + Sentinel + 性能调优

生产实战:Nacos + Sentinel + 性能调优 📖 前置阅读:本文假设读者已掌握 OpenFeign 的配置和容错机制。如果还不熟悉,建议先阅读 OpenFeign 核心概念与快速上手 和 进阶——配置、拦截器与容错。 一、⚡ Feign 调通了——但生产环境的三块拼图还缺着 前两篇搞定了 Feign 的基本用法、超时、重试、拦截器、Fallback。但生产环境还有三件事必须做: ① Feign + Nacos —— 不再写死 URL——服务自动发现、负载均衡 ② Feign + Sentinel —— 被调服务慢/挂了——熔断降级保护调用方 ③ Feign + 性能调优 —— Gzip 压缩、连接池、异步并发 二、🧩 Feign + Nacos 服务发现——零 URL 硬编码 2.1 依赖 <dependencies> <!-- OpenFeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- Nacos 服务发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- LoadBalancer——Feign 自动集成——不需要显式引入 --> </dependencies> 2.2 配置 spring: application: name: order-service cloud: nacos: discovery: server-addr: localhost:8848 namespace: production # 命名空间——隔离环境 group: ORDER_GROUP # 分组 // Feign 接口——只声明服务名,不写 URL @FeignClient(name = "user-service") // Nacos 中有 user-service 这个服务 public interface UserClient { @GetMapping("/api/users/{userId}") User getUser(@PathVariable("userId") Long userId); } 2.3 负载均衡策略 Feign 默认用 Spring Cloud LoadBalancer——轮询策略。想换成随机或加权策略: ...

十二月 12, 2022 · 7 分钟 · 1285 字 · yaomingye

OpenFeign 进阶——配置、拦截器与容错

进阶指南:配置、拦截器与容错 📖 前置阅读:本文假设读者已掌握 OpenFeign 的基本用法——@FeignClient、注解映射。如果还不熟悉,建议先阅读 OpenFeign 核心概念与快速上手。 一、⚡ 调通了——但第二天线上就出问题 Feign 的基本调用 5 分钟搞定。但一上生产——问题一个接一个: 问题 ①:用户服务偶尔慢 2 秒——订单服务的 Feign 一直等——线程全卡死 → 需要超时配置 问题 ②:网络抖动——请求偶尔失败——直接抛异常给用户 → 需要重试机制 问题 ③:用户服务需要 Token 鉴权——每次调 Feign 都要手动传 Header → 需要拦截器自动注入 问题 ④:用户服务挂了——Feign 调不通——订单服务的线程池被占满 → 需要 Fallback 降级 问题 ⑤:排查问题——Feign 到底发了什么请求?返回了什么? → 需要日志 这一篇把以上每个问题都给出具体配置和代码。 二、⏱️ 超时与重试——Feign 最容易被忽略的配置 2.1 默认的超时太长了 Feign 底层用 Ribbon(老版本)或 LoadBalancer(新版本)做负载均衡。默认超时: 参数 默认值 说明 connect-timeout 1s 建立 TCP 连接的超时——默认还好 read-timeout 60s 等响应的超时——太长了!一个慢请求能卡 60 秒 # application.yml——Feign 超时配置 spring: cloud: openfeign: client: config: # ① 全局配置——对所有 FeignClient 生效 default: connect-timeout: 3000 # 建连接最多等 3s read-timeout: 5000 # 等响应最多等 5s logger-level: BASIC # ② 按服务配置——针对特定服务 user-service: # 这个名字和 @FeignClient(name="user-service") 对应 connect-timeout: 2000 read-timeout: 3000 # 用户服务是核心——超时设短点 product-service: connect-timeout: 5000 read-timeout: 10000 # 商品服务偶尔慢——多给点时间 2.2 重试——哪些请求能重试,哪些不能 spring: cloud: openfeign: client: config: default: retryer: com.example.feign.DefaultRetryer # 自定义重试器 // 自定义重试策略 @Configuration public class FeignRetryConfig { @Bean public Retryer feignRetryer() { // 参数:period(初始间隔), maxPeriod(最大间隔), maxAttempts(最多尝试次数) // 下面 = 初始等 100ms → 每次乘 1.5 → 最多重试 3 次(总共 4 次) return new Retryer.Default(100, 1500, 3); } } 重试的时间线: 第 1 次请求 → 失败 → 等 100ms 第 2 次请求 → 失败 → 等 250ms 第 3 次请求 → 失败 → 等 625ms 第 4 次请求 → 成功 → 返回 如果第 4 次也失败 → 抛异常 ⚠️ 新手提示:POST 请求不要重试!如果创建订单的 POST 请求超时——Feign 自动重试——用户被扣了两次钱。GET 可以重试(幂等),POST/PUT/DELETE 绝不重试。要控制这个——用 @FeignClient 的 configuration 属性对不同接口用不同的重试策略。 ...

十二月 11, 2022 · 6 分钟 · 1144 字 · yaomingye

Sentinel 系统规则与生产部署

Sentinel 生产部署 📖 前置阅读:本文假设读者已掌握 Sentinel 流控和熔断规则。如果还不熟悉,建议先阅读前三篇:核心概念、流控规则、熔断降级。 一、⚡ 流控和熔断都配了——但整个机器的 CPU 飙到 95% 了 流控规则保护的是单个接口——“getUser 每秒最多 100 个”。“熔断规则保护的是接口自身故障——“getUser 50% 慢调用就熔断”。 但这些规则不保护整个机器——如果 20 个接口各自都没超过自己的 QPS 阈值,但加起来把机器的 CPU 打满了——所有接口不可用。 系统规则(System Rule)解决的就是这个问题——从整个应用的层面做自适应保护。 二、🧬 系统自适应保护——不配具体 QPS,配"健康指标” 2.1 五种系统规则 // 系统规则——对整个服务生效——不是针对某个资源 SystemRule systemRule = new SystemRule(); // ① Load 保护——系统负载(仅 Linux)超过阈值时限流 systemRule.setHighestSystemLoad(4.0); // CPU 核数——如 4 核 CPU // 系统 Load > 4.0 时——所有入口 QPS 自动降到 (Load / 当前Load) * 当前QPS // ② CPU 使用率保护 systemRule.setHighestCpuUsage(0.8); // CPU 使用率 > 80% 时——拒绝新的入口请求 // ③ 平均 RT 保护 systemRule.setAvgRt(100); // 所有入口的平均 RT > 100ms 时——限流 // ④ 最大并发线程数 systemRule.setMaxThread(200); // 并发线程数 > 200——拒绝新请求 // ⑤ 入口 QPS——这个最直接 systemRule.setQps(500); // 所有入口(不管是哪个资源)——总 QPS > 500 系统规则 指标 阈值建议 适用场景 Load 系统 Load ≤ CPU 核数 Linux 环境——最推荐 CPU 使用率 CPU usage ≤ 80% 跨平台——和 Load 二选一 平均 RT 所有入口平均 RT ≤ 正常值 × 2 服务变慢时自动降 QPS 并发线程数 并发线程数 ≤ 线程池大小 防止线程池满 入口 QPS 总 QPS ≤ 压测值 × 80% 简单粗暴——兜底方案 2.2 系统规则的最佳组合 @Component public class SystemRuleInitializer implements ApplicationRunner { @Override public void run(ApplicationArguments args) { List<SystemRule> rules = new ArrayList<>(); // 规则 1:Load 保护——系统负载过高时自动降 QPS SystemRule loadRule = new SystemRule(); loadRule.setHighestSystemLoad(4.0); rules.add(loadRule); // 规则 2:平均 RT 保护——接口变慢时自动减速 SystemRule rtRule = new SystemRule(); rtRule.setAvgRt(200); rules.add(rtRule); // 规则 3:并发线程数保护——防止线程池满 SystemRule threadRule = new SystemRule(); threadRule.setMaxThread(300); rules.add(threadRule); SystemRuleManager.loadRules(rules); } } 系统规则是整个 JVM 级别的——不需要指定资源名。它的作用范围是所有入口(所有经过 Sentinel 保护的入口流量的汇总)。 ...

十二月 9, 2022 · 5 分钟 · 1042 字 · yaomingye

Sentinel 熔断降级规则

Sentinel 熔断降级 📖 前置阅读:本文假设读者已掌握 Sentinel 流控规则和 blockHandler/fallback 的基本用法。如果还不熟悉,建议先阅读 Sentinel 核心概念与快速上手 和 Sentinel 流控规则全解。 一、⚡ 限流是自己控制的——但接口突然变慢是意外 你给 getUser 接口配了 QPS 限流 = 100——这是主动控制。但有一天数据库查询从 50ms 涨到了 5s——不是流量大,是接口本身出问题了。 这 5s 的查询会带来一连串的后果: getUser 每次耗时 5s → 调它的 100 个请求都在等——线程池 100 个线程全占满 → 其他接口没线程可用——跟着一起 502 → 上游调 getUser 的 10 个服务全超时——各自线程池也满 → 整个系统雪崩 限流解决不了这个问题——100 QPS 还是 100 QPS,只是每个请求都慢到 5s。熔断降级解决的就是"接口自己出问题"——检测到异常主动切断对故障接口的调用——等它恢复了再放行。 二、🔄 熔断器状态机——每个熔断器都一样 不管是 Sentinel、Hystrix 还是 Resilience4j,熔断器的状态机都是一样的——三个状态: stateDiagram-v2 [*] --> CLOSED : 初始状态 CLOSED --> OPEN : 失败率达到阈值 OPEN --> HALF_OPEN : 熔断时间窗口结束 HALF_OPEN --> CLOSED : 试探请求成功 HALF_OPEN --> OPEN : 试探请求失败 note right of CLOSED : 正常——请求正常通过\n持续统计指标 note right of OPEN : 熔断——请求直接拒绝\n不调后端——直接 fallback note right of HALF_OPEN : 半开——放一个试探请求\n看它能不能成功 状态 行为 进入条件 CLOSED(关闭) 正常通过——统计指标 初始状态——或 HALF_OPEN 试探成功 OPEN(打开) 直接拒绝——不走后端——直接调 fallback 指标达到阈值 HALF_OPEN(半开) 放一个试探请求——其他拒绝 OPEN 持续一段时间后自动进入 三、🧬 Sentinel 的三种熔断策略 Sentinel 支持三种熔断策略——比 Hystrix(只支持异常比例)更精细: ...

十二月 8, 2022 · 4 分钟 · 672 字 · yaomingye

Sentinel 流控规则全解

Sentinel 流控规则 📖 前置阅读:本文假设读者已掌握 Sentinel 的核心概念——资源/规则/Entry 类型。如果还不熟悉,建议先阅读 Sentinel 核心概念与快速上手。 一、⚡ “每秒 100 个 QPS"只是流控的冰山一角 上一篇说了 FlowRule —— “QPS 超过 100 就拒绝”。但真实的需求远比这复杂: 场景 ①:新服务刚启动——JIT 还没热身——扛不住满负荷流量 → 需要"预热"——先 10 QPS,逐步升到 100 QPS 场景 ②:不想直接拒绝请求——让请求排队等着 → 需要"排队等待"——请求等 500ms 能排上就处理,超时就拒绝 场景 ③:支付接口出问题——我不想限流它——但我想限流"调用了支付接口"的接口 → 需要"关联限流"——支付接口 QPS 高了——限流订单创建接口(让压力源头降流量) 场景 ④:同一个 URL 被两个入口调用——我只想限流其中一个入口 → 需要"链路限流"——只限制从某个入口进来的流量 这四个场景对应 Sentinel 流控的三种效果 × 三种策略: 每条 FlowRule 有两个关键选择: ① 效果(ControlBehavior)——超过阈值后怎么办? ② 策略(Strategy)——针对谁来限流? 二、📊 两种 Grade —— 限制了"什么” 2.1 QPS 模式(FLOW_GRADE_QPS) 每秒请求次数——最常用: FlowRule rule = new FlowRule(); rule.setResource("getUser"); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 基于 QPS rule.setCount(100); // 阈值:每秒 100 个 时间线(1 秒内): 第 1~100 个请求 → 通过 第 101 个请求 → 被拒绝(BlockException) 下一秒重新计数 QPS 限流的核心是滑动窗口计数器——统计最近 1 秒(可配)的请求数。 ...

十二月 7, 2022 · 4 分钟 · 819 字 · yaomingye

Gateway 生产实战——鉴权、限流、熔断与部署

Gateway 生产实战 📖 前置阅读:本文假设读者已掌握 Gateway 的 Route/Predicate/Filter 全操作。如果还不熟悉,建议先阅读前三篇:核心概念、Predicate 全解、Filter 全操作。 一、⚡ 路由和 Filter 都调通了——但你能上线吗? 开发环境一切正常——localhost 上 Gateway 跑得稳稳的。但上线之前你至少还要解决: ① 认证——用户登录后的 JWT Token 在网关统一校验 ② 限流——防止恶意刷接口——一个 IP 一秒最多 10 次 ③ 熔断——后端挂了——网关直接降级返回而不是把 500 抛给前端 ④ 跨域——前端从不同域名调网关——浏览器会拦截 ⑤ 监控——请求量、错误率、延迟——全部看不到就是盲飞 ⑥ TraceId——一个请求穿过网关到后端多个服务——怎么串联日志? 这一篇把以上每个问题都给出可直接使用的配置和代码。 二、🔐 JWT 鉴权——全局统一校验 2.1 为什么在网关做鉴权? 每个后端服务都自己解析 JWT——重复代码、分散维护、容易漏掉。在网关统一做——后端只信任网关传过来的 Header 就行了: 浏览器带 JWT → 网关解析 → Header 中放 userId + role → 后端直接用 2.2 完整的 JWT 鉴权 GlobalFilter @Component @Order(-100) public class JwtAuthGlobalFilter implements GlobalFilter { // 白名单——不需要 Token 的接口 private static final List<String> WHITE_LIST = List.of( "/api/public/login", "/api/public/register", "/api/public/health" ); // 从配置中心拿——这里简化为常量 private static final String SECRET_KEY = "your-256-bit-secret-key"; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String path = exchange.getRequest().getURI().getPath(); // ① 白名单放行 if (isWhiteListed(path)) { return chain.filter(exchange); } // ② 提取 Token String authHeader = exchange.getRequest() .getHeaders().getFirst(HttpHeaders.AUTHORIZATION); if (authHeader == null || !authHeader.startsWith("Bearer ")) { return unauthorized(exchange, "缺少认证 Token"); } String token = authHeader.substring(7); // ③ 解析 JWT try { Claims claims = Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); // 检查是否过期 if (claims.getExpiration().before(new Date())) { return unauthorized(exchange, "Token 已过期"); } // ④ 把用户信息写入请求头——后端直接用 ServerHttpRequest mutatedRequest = exchange.getRequest().mutate() .header("X-User-Id", String.valueOf(claims.get("userId"))) .header("X-User-Name", claims.get("userName", String.class)) .header("X-User-Role", claims.get("role", String.class)) .build(); // ⑤ 用修改后的 Request 继续 return chain.filter(exchange.mutate().request(mutatedRequest).build()); } catch (JwtException e) { return unauthorized(exchange, "Token 无效: " + e.getMessage()); } } private boolean isWhiteListed(String path) { return WHITE_LIST.stream().anyMatch(path::startsWith); } private Mono<Void> unauthorized(ServerWebExchange exchange, String message) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); exchange.getResponse().getHeaders() .setContentType(MediaType.APPLICATION_JSON); // 返回 JSON 错误信息 byte[] body = ("{\"code\":401,\"message\":\"" + message + "\"}").getBytes(); DataBuffer buffer = exchange.getResponse() .bufferFactory().wrap(body); return exchange.getResponse().writeWith(Mono.just(buffer)); } } 2.3 后端如何信任网关 后端服务应该只信任从网关来的请求——加一个内部 Token 做服务间认证: ...

十二月 5, 2022 · 8 分钟 · 1502 字 · yaomingye

GatewayFilter 与 GlobalFilter 全操作

GatewayFilter 与 GlobalFilter 📖 前置阅读:本文假设读者已掌握 Route 和 Predicate 的配置方式。如果还不熟悉,建议先阅读 Spring Cloud Gateway 核心概念与快速上手 和 Predicate 与路由规则全解。 一、⚡ 路由转发了——但在转发前后你还想做很多事 Predicate 决定了请求走哪条路——但路上你还要做很多事: 请求 → 网关 → 后端 —— 转发过程中: ① 把 /api/users/1 转成 /1(去掉前缀) ② 自动加上 Header(X-Request-Id、X-Source) ③ 限制每个 IP 每秒只能调 10 次 ④ 请求失败时自动重试 3 次 ⑤ 把用户信息写入 Header(后端不用自己解析 JWT) ⑥ 后端 3 次失败后熔断——直接降级返回 这些全都靠 Filter 实现。Gateway 的 Filter 分两种——GatewayFilter(针对特定路由)和 GlobalFilter(针对所有路由)。 二、🧩 Filter 的执行模型——Pre Filter 和 Post Filter 一个 Filter 可以在两个阶段做事: public class DemoFilter implements GatewayFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // ===== Pre Filter:转发到后端之前执行 ===== System.out.println("① 请求进来了——做鉴权、限流、加 Header"); return chain.filter(exchange) // ← 转发到后端(或者说交给下一个 Filter) .then(Mono.fromRunnable(() -> { // ===== Post Filter:后端返回后执行 ===== System.out.println("⑤ 后端响应了——做日志、修改响应体"); })); } } 时间线: ① Pre Filter(鉴权) ② 下一个 Filter 的 Pre(限流) ③ 转发到后端 ④ 后端返回响应 ⑤ 当前 Filter 的 Post(修改响应) ⑥ 上一个 Filter 的 Post(记录日志) 这个链式结构是 WebFlux 的 Mono.then() 实现的——不是阻塞等待,而是注册回调。 ...

十二月 4, 2022 · 7 分钟 · 1281 字 · yaomingye

Predicate 与路由规则全解

Predicate 与路由规则 📖 前置阅读:本文假设读者已理解 Route/Predicate/Filter 三要素和 Gateway 的基本用法。如果还不熟悉,建议先阅读 Spring Cloud Gateway 核心概念与快速上手。 一、⚡ Path 匹配太简单了——直到你遇到了这些需求 上一篇用 Path=/api/users/** 把请求按路径转发——基本路由够用了。但真实场景远不止于此: 需求 1:灰度发布——10% 的流量走 v2 版本,90% 走 v1 需求 2:内网用户走内网地址,外网用户走外网地址 需求 3:大促活动只在 12 月 1 日到 12 月 12 日生效——过期自动关闭 需求 4:带特定 Header(X-Tenant=alibaba)的请求路由到专门的集群 需求 5:GET 请求走缓存集群,POST/PUT/DELETE 走主集群 这些需求全都靠 Predicate 实现。Predicate 不只有 Path——Spring Cloud Gateway 内置了 12 种 Predicate Factory。 二、📖 记住 Predicate 的命名规则 Spring Cloud Gateway 的 Predicate 在配置时有一个命名转换: Java 类名: CookieRoutePredicateFactory ↓ 去掉 "RoutePredicateFactory" 后缀 配置名: Cookie=xxx 所有 Predicate 都是这个规则:HeaderRoutePredicateFactory → Header,QueryRoutePredicateFactory → Query。知道这个后——看到一个配置名就能找到对应的源码。 ...

十二月 3, 2022 · 6 分钟 · 1226 字 · yaomingye

gRPC Gateway 与生产环境部署

gRPC-Gateway:让前端也能调 gRPC 📖 前置阅读:本文假设读者已完成 gRPC 服务的开发和微服务拆分。如果还不熟悉,建议先阅读 SpringBoot gRPC 全操作指南 和 微服务拆分实战:以 proto 为契约。 一、⚡ gRPC 最大的问题:浏览器不支持 你花了两周把微服务之间的通信全换成了 gRPC——性能翻了 3 倍,Protobuf 二进制传输省了 60% 带宽。看起来很完美。 然后前端同事找来了:“你的接口怎么调?Postman 发 HTTP 请求连不上。" 这就是 gRPC 最大的现实问题——gRPC 基于 HTTP/2,浏览器不直接支持 gRPC 协议。你在浏览器里 fetch('http://localhost:9090/...') 是调不通的——浏览器不会说 gRPC。 解决方案是gRPC-Gateway——在 gRPC 服务前面放一个网关,对外提供标准的 HTTP RESTful JSON 接口,对内转成 gRPC 调用: 浏览器/移动端/curl(HTTP/1.1 JSON) ↓ [gRPC-Gateway / Envoy / grpc-web] ← 协议转换层 ↓ gRPC(HTTP/2 Protobuf) [gRPC Server] 二、🔌 方案选择:三种网关方案 方案 原理 适用场景 复杂度 gRPC-Gateway 从 proto 自动生成反向代理代码——HTTP JSON ↔ gRPC 转换 gRPC 服务需要同时支持 HTTP JSON 和 gRPC 调用方 中 Envoy gRPC-JSON Transcoder Envoy 代理层做协议转换——不需要修改代码 有服务网格——统一的入口网关 中 grpc-web + Envoy 浏览器用 grpc-web 协议(HTTP/1.1),Envoy 转成 gRPC 前端直接在浏览器中调 gRPC(不需要 REST 包装) 高 本文重点讲方案一 gRPC-Gateway——它最直接、不需要额外的代理基础设施、和 SpringBoot 整合最简单。 ...

十二月 1, 2022 · 10 分钟 · 2072 字 · yaomingye
Cat Radio