Multithreading 多线程调用同一函数时出现问题

Multithreading 多线程调用同一函数时出现问题,multithreading,kotlin,thread-safety,micrometer,spring-micrometer,Multithreading,Kotlin,Thread Safety,Micrometer,Spring Micrometer,在我的代码中,我有两次对一个应用程序的rest调用,即使调用是对同一个端点的,我想用千分尺来区分调用。为此,我尝试添加一个新字段,如下所示 @Component class MyMeterFilter : MeterFilter { var isRequired: Boolean = false override fun map(id: Meter.Id): Meter.Id { return if (id.name.startsWith("http")) {

在我的代码中,我有两次对一个应用程序的rest调用,即使调用是对同一个端点的,我想用千分尺来区分调用。为此,我尝试添加一个新字段,如下所示

@Component
class MyMeterFilter : MeterFilter {

    var isRequired: Boolean = false
    override fun map(id: Meter.Id): Meter.Id {
        return if (id.name.startsWith("http")) {
            id.withTag(Tag.of("extra.tag", isRequired.toString()))
        } else id
    }

}

在进行第一次调用之前,我将isRequired字段设置为true,在进行第二次调用之前,我将其设置为false(两个调用都是来自单例bean的异步调用)。但正如您从代码中看到的,由于只创建了一个类实例,isRequired的值在两个调用之间被覆盖。如何避免它?

如果它基于调用的线程
ThreadLocal
可以保持该状态,则
MeterFilter
可以检查它,只要确保在完成调用后清除
ThreadLocal

似乎您正试图在
http.server.request
度量上设置额外的标记,对吗?这很聪明

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
class MetricDecoratingFilter : OncePerRequestFilter(), MeterFilter {
    private val additionalTags = ThreadLocal<Tags>()

    override fun doFilterInternal(req: HttpServletRequest, resp: HttpServletResponse, chain: FilterChain) {
        //add logic to compute the tags
        additionalTags.set(Tags.of("app", "bob"))
        chain.doFilter(req, resp)
        additionalTags.remove()
    }

    override fun map(id: Meter.Id): Meter.Id {
        return if (id.name.startsWith("http")) {
            val moreTags = additionalTags.get()
            id.withTags(moreTags)
        } else id
    }
}
@组件
@顺序(有序。最高优先级)
类MetricDecoratingFilter:OncePerRequestFilter(),MeterFilter{
private val additionalTags=ThreadLocal()
重写fun doFilterInternal(请求:HttpServletRequest,响应:HttpServletResponse,链:FilterChain){
//添加逻辑以计算标记
additionalTags.set(标记(“应用程序”、“鲍勃”))
链式过滤器(req,resp)
additionalTags.remove()
}
覆盖趣味地图(id:Meter.id):Meter.id{
返回if(id.name.startsWith(“http”)){
val moreTags=additionalTags.get()
id.withTags(更多标签)
}其他id
}
}

如果基于调用线程的线程,则
ThreadLocal
可以保持该状态,
MeterFilter
可以对其进行检查,只需确保在完成后清除
ThreadLocal

似乎您正试图在
http.server.request
度量上设置额外的标记,对吗?这很聪明

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
class MetricDecoratingFilter : OncePerRequestFilter(), MeterFilter {
    private val additionalTags = ThreadLocal<Tags>()

    override fun doFilterInternal(req: HttpServletRequest, resp: HttpServletResponse, chain: FilterChain) {
        //add logic to compute the tags
        additionalTags.set(Tags.of("app", "bob"))
        chain.doFilter(req, resp)
        additionalTags.remove()
    }

    override fun map(id: Meter.Id): Meter.Id {
        return if (id.name.startsWith("http")) {
            val moreTags = additionalTags.get()
            id.withTags(moreTags)
        } else id
    }
}
@组件
@顺序(有序。最高优先级)
类MetricDecoratingFilter:OncePerRequestFilter(),MeterFilter{
private val additionalTags=ThreadLocal()
重写fun doFilterInternal(请求:HttpServletRequest,响应:HttpServletResponse,链:FilterChain){
//添加逻辑以计算标记
additionalTags.set(标记(“应用程序”、“鲍勃”))
链式过滤器(req,resp)
additionalTags.remove()
}
覆盖趣味地图(id:Meter.id):Meter.id{
返回if(id.name.startsWith(“http”)){
val moreTags=additionalTags.get()
id.withTags(更多标签)
}其他id
}
}