**高并发、微服务 、性能调优实战案例100讲，所有案例均源于个人工作实战，均配合代码落地**

加我微信：itsoku，所有案例均提供在线答疑。



# 第42节 微服务中如何传递公共参数？

<span style="font-weight:bold; color:red">目前整个课程59块钱，100个案例，含所有源码 & 文档 & 技术支持，可点击左下角小黄车了解</span>



## 1、本文内容

本文是微服务中大概率会用到的一个知识点，非常实用，请大家用心看完。



## 2、背景

先来看下微服务调用的流程图：https://www.processon.com/view/link/665457cd50771c4b1ea0905b?cid=6654521d659699314de163c5

![](img/微服务中如何传递公共参数.png)

## 3、有5个地方需要考虑

### 1）、gateway将公共参数放到请求中传递给下层服务

gateway转发请求前，将公共的参数添加请求头中向下传递便可。

### 2）、微服务中需要一个Filter读取公共参数丢到ThreadLocal中

```java
com.itsoku.lesson042.common.context.SystemContextFilter

com.itsoku.lesson042.common.context.SystemContext
com.itsoku.lesson042.common.context.SystemContextHolder
```

### 3）、OpenFeign发送请求前，将公共参数丢到请求头中进行传递

```java
com.itsoku.lesson042.common.context.SystemContextRequestInterceptor
    
public class SystemContextRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        // 从ThreadLocal中拿到公共上线文参数，放到 OpenFeign 请求头中
        for (Pair<String, String> header : SystemContextHolder.getSystemContext().toHeaders()) {
            template.header(header.getKey(), header.getValue());
        }
    }
}
```

### 4）、RestTemplate发送请求前，将公共参数丢到请求头中进行传递

```java
com.itsoku.lesson042.common.context.SystemContextRestTemplateRequestCustomizer
    
public class SystemContextRestTemplateRequestCustomizer implements RestTemplateRequestCustomizer {
    @Override
    public void customize(ClientHttpRequest request) {
        // 从ThreadLocal中拿到公共上线文参数，放到 RestTemplate 请求头中
        for (Pair<String, String> header : SystemContextHolder.getSystemContext().toHeaders()) {
            request.getHeaders().add(header.getKey(), header.getValue());
        }
    }
}
```

RestTemplate定义需要采用下面这种方式

```java
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.build();
}
```

### 5）、线程池中需要要能够读取到这些公共参数

需要使用我们自定义的线程池，如下

```java
com.itsoku.lesson042.common.thread.CommonThreadPoolExecutor
```

重写了submit和execute方法，可以实现调用者和线程池间ThreadLocal中的数据共享。

看个案例，代码如下，这里会将公共参数放到线程池的线程中

```java
private ThreadPoolExecutor threadPoolExecutor = new CommonThreadPoolExecutor(new CommonThreadPoolExecutor.ThreadLocalContext() {
    @Override
    public Object getContext() {
        return SystemContextHolder.getSystemContext().getContextMap();
    }

    @Override
    public void setContext(Object context) {
        SystemContextHolder.getSystemContext().getContextMap().putAll((Map<? extends String, ? extends String>) context);
    }
}, 5, 5, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100));
```



## 4、测试用例

### 1）准备2个服务

- service1：com.itsoku.lesson042.service1.Lesson042Service1Application
- service2：com.itsoku.lesson042.service2.Lesson042Service2Application

### 2）service1中测试5中情况，代码如下

```
com.itsoku.lesson042.service1.Service1Controller#test1
```

### 3）运行看效果

src/test/resources/Service1Controller.http

```http
### 上下文测试
GET http://localhost:8080/service1/test1
itsoku-header-user_id: 10001
itsoku-header-local: zh_cn
itsoku-header-user_name: luren
```

### 4）走gateway看下效果

启动gateway服务

```
com.itsoku.lesson042.gateway.Lesson042GatewayApplication
```

通过gateway去访问刚才上面的接口

```http
### 走 gateway 访问 service1中的test1 接口
GET http://localhost:8080/lesson042-service1/service1/test1
itsoku-header-local: zh_cn
token: itsoku
```

这个请求会打到gateway，gateway中我们搞了个拦截器，如下，这里面会校验token，验证通过后，会放入用户id和用户名

```java
com.itsoku.lesson042.gateway.AuthFilter
```

运行测试用例看效果



## 5、源码

源码在lesson042这个模块中，需要的小伙伴可以加我微信：itsoku，获取。



# 高并发 & 微服务 & 性能调优实战案例100讲

## 已更新 42 节课

<span style="font-weight:bold; color:red">目前整个课程59块钱，含所有源码 & 文档 & 技术支持，一杯咖啡的价格，还没下手的朋友，赶紧了，马上要涨价了</span>。

```java
1. 分片上传实战
2. 通用并发处理工具类实战
3. 实现一个好用接口性能压测工具类
4. 超卖问题的4种解决方案，也是防止并发修改数据出错的通用方案
5. Semaphore实现接口限流实战
6. 并行查询，优化接口响应速度实战
7. 接口性能优化之大事务优化
8. 通用的Excel动态导出功能实战
9. 手写线程池管理器，管理&监控所有线程池
10. 动态线程池
11. SpringBoot实现动态Job实战
12. 并行查询，性能优化利器，可能有坑
13. 幂等的4种解决方案，吃透幂等性问题
14. 接口通用返回值设计与实现
15. 接口太多，各种dto、vo不计其数，如何命名？
16. 一个业务太复杂了，方法太多，如何传参？
17. 接口报错，如何快速定位日志？
18. 线程数据共享必学的3个工具类：ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal
19. 通过AOP统一打印请求链路日志，排错效率飞升
20. 大批量任务处理常见的方案（模拟余额宝发放收益）
21. 并发环境下，如何验证代码是否正常？
22. MySql和Redis数据一致性
23. SpringBoot数据脱敏优雅设计与实现
24. 一行代码搞定系统操作日志
25. Aop简化MyBatis分页功能
26. ThreadLocal 遇到线程池有大坑 & 通用解决方案
27. SpringBoot读写分离实战（一个注解搞定读写分离 && 强制路由主库）
28. MQ专题-MQ典型的使用场景
29. MQ专题-如何确保消息的可靠性
30. MQ专题-SpringBoot中，手把手教你实现事务消息
31. 手写一个好用的延迟任务处理工具类
32. MQ专题-MQ延迟消息通用方案实战
33. MQ消息幂等消费 & 消费失败衰减式重试通用方案 & 代码 & 文档
34. MQ专题：顺序消息通用方案实战 & 代码落地 & 文档
35. MQ专题：消息积压相关问题及解决思路
36. 分布式事务-MQ最终一致性-实现跨库转账（案例+源码+文档）
37. 分布式事务-MQ最终一致性-实现电商账户余额提现到微信钱包（案例+源码+文档）
38. 分布式事务：通用的TCC分布式事务生产级代码落地实战
39. 分布式锁详解
40. 分享一个特别好用的Redissson分布式锁工具类
41. 一个注解轻松搞定分布式锁
42. 微服务中如何传递公共参数？
```



## 课程部分大纲，连载中。。。。

以下课程均来源于个人多年的实战，均提供原理讲解 && 源码落地

1. 分片上传实战
2. 通用并发处理工具类实战
3. 实现一个好用接口性能压测工具类
4. 超卖问题的4种解决方案，也是防止并发修改数据出错的通用方案
5. Semaphore实现接口限流实战
6. 并行查询，优化接口响应速度实战
7. 接口性能优化之大事务优化
8. 通用的Excel动态导出功能实战
9. 手写线程池管理器，管理&监控所有线程池
10. 动态线程池
11. SpringBoot实现动态Job实战
12. 并行查询，性能优化利器，可能有坑
13. 幂等的4种解决方案，吃透幂等性问题
14. 接口通用返回值设计与实现
15. 接口太多，各种dto、vo不计其数，如何命名？
16. 一个业务太复杂了，方法太多，如何传参？
17. 接口报错，如何快速定位日志？
18. 线程数据共享必学的3个工具类：ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal
19. 通过AOP统一打印请求链路日志，排错效率飞升
20. 大批量任务处理常见的方案（模拟余额宝发放收益）
21. 并发环境下，如何验证代码是否正常？
22. MySql和Redis数据一致性
23. SpringBoot数据脱敏优雅设计与实现
24. 一行代码搞定系统操作日志
25. Aop简化MyBatis分页功能
26. ThreadLocal 遇到线程池有大坑 & 通用解决方案
27. SpringBoot读写分离实战（一个注解搞定读写分离 && 强制路由主库）
28. MQ专题：MQ典型的7种使用场景
29. MQ专题：如何确保消息的可靠性
30. MQ专题：SpringBoot中，手把手教你实现事务消息
31. 手写一个好用的延迟任务处理工具类
32. MQ专题：延迟消息通用方案实战
33. MQ专题：消息幂等消费 & 消费失败自动重试通用方案 & 代码落地
34. MQ专题：顺序消息通用方案实战
35. MQ专题：消息积压问题
36. 分布式事务-MQ最终一致性-实现跨库转账（案例+源码+文档）
37. 分布式事务-MQ最终一致性-实现电商账户余额提现到微信钱包（案例+源码+文档）
38. 分布式事务：通用的TCC分布式事务生产级代码落地实战
39. 分布式锁
40. 分享一个特别好用的Redissson分布式锁工具类
41. 分布式锁：一个注解轻松实现布式锁
42. 微服务中如何传递上下文？实战
43. 微服务链路日志追踪实战（原理&代码落地）
44. SpringBoot实现租户数据隔离
45. MyBatis进阶：封装MyBatis，实现通用的无SQL版CRUD功能，架构师必备
46. MyBatis进阶：自己实现通用分表功能，架构师必备
47. MyBatis进阶：实现多租户隔离ORM框架
48. SpringBoot中实现自动监听PO的变化，自动生成表结构
49. SpringBoot优雅停机
50. 分布式专题：其他实战课程等
51. 性能调优：如何排查死锁？
52. 性能调优：如何排查内存溢出？
53. 性能调优：CPU被打满，如何排查？
54. 性能调优：生产代码没生效，如何定位？
55. 性能调优：接口太慢，如何定位？
56. 性能调优：如何查看生产上接口的入参和返回值？
57. 性能调优：远程debug
58. 生产上出现了各种故障，如何定位？
59. db和缓存一致性，常见的方案
60. Redis场景案例。。。
61. 系统资金账户设计案例（一些系统涉及到资金操作）
62. 工作中常见的场景案例设计与实现。。。