当前位置: 首页 > news >正文

如何自己做淘宝客网站关键词优化的策略有哪些

如何自己做淘宝客网站,关键词优化的策略有哪些,铜山网站开发,岗顶做网站公司用户会话信息在异步事件/线程池的传递 author:shengfq date:2024-07-29 version:1.0 背景: 同事写的一个代码功能,是在一个主线程中通过如下代码进行异步任务的执行,结果遇到了问题. 1.ThreadPool.execute(Runnable)启动一个子线程执行异步任务 2.applicationContext.publis…

用户会话信息在异步事件/线程池的传递

@author:shengfq
@date:2024-07-29
@version:1.0

背景:

同事写的一个代码功能,是在一个主线程中通过如下代码进行异步任务的执行,结果遇到了问题.
1.ThreadPool.execute(Runnable)启动一个子线程执行异步任务
2.applicationContext.publishEvent(applicationEvent)启动一个异步事件执行异步任务

问题:

由于异步任务线程内也需要用户的身份会话信息UserDetail对象,他将该对象作为payload直接从主线程通过方法传递进去(硬编码),导致业务方法带了个UserDetail的参数,而且进入到子线程后,通过DetailHelper.setUserDetail(UserDetail)这种方式将会话数据放入Context后,执行service方法却意外清理了UserDetail对象.为什么会出现这种情况? 用户会话信息在这种场景下如何传递比较合适?

@Async(ThreadPoolName)
@EventListener(PublishEvent event){UserDetail userDetail=event.getPayload();DetailHelper.setUserDetail(userDetail);...DetailHelper.getUserDetail();//是null
}
实现原理:

通过定制化线程池对象ThreadPoolExecutor的submit(),进行包装,将Context的用户信息通过方法传参给子线程的ContextHolder.

代码如下:

1. ITask ICallback 这是执行异步任务的抽象,每个任务一个类一个回调
public interface ITask {/**执行异步任务*/void executeTask();
}public interface ICallback {/**是否执行成功*/void callback(boolean result);
}
2. EssContextHolder 线程变量上下文

package org.hzero.samples.core.context;/*** 线程变量上下文*/
public class EssContextHolder {private EssContextHolder() {}/*** sid*/private final static ThreadLocal<String> SID = new ThreadLocal<>();/*** token*/private final static ThreadLocal<String> TOKEN = new ThreadLocal<>();/*** 联盟code*/private final static ThreadLocal<String> UNION_CODE = new ThreadLocal<>();/*** 联盟unionId*/private final static ThreadLocal<String> UNION_ID = new ThreadLocal<>();/*** 设置SID** @param sid*/public static void setSID(String sid) {EssContextHolder.SID.set(sid);}/*** 获取SID*/public static String getSID() {return EssContextHolder.SID.get();}/*** 设置TOKEN** @param token*/public static void setToken(String token) {EssContextHolder.TOKEN.set(token);}/*** 获取TOKEN*/public static String getToken() {return EssContextHolder.TOKEN.get();}/*** 设置unionCode*/public static void setUnionCode(String unionCode) {EssContextHolder.UNION_CODE.set(unionCode);}/*** 获取unionCode*/public static String getUnionCode() {return EssContextHolder.UNION_CODE.get();}/*** 设置unionId*/public static void setUnionId(String unionId) {EssContextHolder.UNION_ID.set(unionId);}/*** 获取联盟unionId*/public static String getUnionId() {return EssContextHolder.UNION_ID.get();}
}
3. ThreadPoolExecutorMdcWrapper 线程池的个性化定制类

package org.hzero.samples.core.context;import org.slf4j.MDC;import java.util.concurrent.*;/*** @ClassName ThreadPoolExecutorMdcWrapper* @Description 线程池的个性化定制类* @Author shengfq* @Date 2021/5/28 0028 上午 10:53* @Version*/
public class ThreadPoolExecutorMdcWrapper extends ThreadPoolExecutor {public ThreadPoolExecutorMdcWrapper(AsyncTaskThreadPoolConfig config, ThreadFactory threadFactory, RejectedExecutionHandler handler ) {this(config.getCorePoolSize(), config.getMaxPoolSize(), config.getKeepAliveSecond(), TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(config.getQueueCapacity()),threadFactory,handler);}public ThreadPoolExecutorMdcWrapper(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue) {super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);}public ThreadPoolExecutorMdcWrapper(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);}public ThreadPoolExecutorMdcWrapper(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);}public ThreadPoolExecutorMdcWrapper(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,RejectedExecutionHandler handler) {super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);}@Overridepublic void execute(Runnable task) {String sid =   EssContextHolder.getSID();String token = EssContextHolder.getToken();String unionId = EssContextHolder.getUnionId();super.execute(ThreadMdcUtil.wrap(sid,token,unionId,task, MDC.getCopyOfContextMap()));}@Overridepublic <T> Future<T> submit(Runnable task, T result) {String sid =   EssContextHolder.getSID();String token = EssContextHolder.getToken();String unionId = EssContextHolder.getUnionId();return super.submit(ThreadMdcUtil.wrap(sid,token,unionId,task, MDC.getCopyOfContextMap()), result);}@Overridepublic <T> Future<T> submit(Callable<T> task) {String sid =   EssContextHolder.getSID();String token = EssContextHolder.getToken();String unionId = EssContextHolder.getUnionId();return super.submit(ThreadMdcUtil.wrap(sid,token,unionId,task, MDC.getCopyOfContextMap()));}@Overridepublic Future<?> submit(Runnable task) {String sid =   EssContextHolder.getSID();String token = EssContextHolder.getToken();String unionId = EssContextHolder.getUnionId();return super.submit(ThreadMdcUtil.wrap(sid,token,unionId,task, MDC.getCopyOfContextMap()));}
}
4. ThreadMdcUtil.java Runnable和Callable的wrap包装,增加环境变量的绑定
package org.hzero.samples.core.context;import org.slf4j.MDC;import java.util.Map;
import java.util.concurrent.Callable;/*** @ClassName ThreadMdcUtil* @Description * @Author shengfq* @Date 2021/5/28 0028 上午 10:54* @Version*/
public class ThreadMdcUtil {public static <T> Callable<T> wrap(final String sid,final String token,final String unionId,final Callable<T> callable, final Map<String, String> context) {return () -> {EssContextHolder.setSID(sid);EssContextHolder.setToken(token);EssContextHolder.setUnionId(unionId);if (context == null) {MDC.clear();} else {MDC.setContextMap(context);}try {return callable.call();} finally {MDC.clear();}};}public static Runnable wrap(final String sid,final String token,final String unionId,final Runnable runnable, final Map<String, String> context) {return () -> {EssContextHolder.setSID(sid);EssContextHolder.setToken(token);EssContextHolder.setUnionId(unionId);if (context == null) {MDC.clear();} else {MDC.setContextMap(context);}try {runnable.run();} finally {MDC.clear();}};}
}
5. ExecuteTaskUtils 异步任务执行器(对调用者开放)
package org.hzero.samples.core.context;import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;import java.util.Map;/*** @ClassName ExecuteTaskUtils* @Description 执行异步线程工具类* @Author shengfq* @Date 2021/5/28 0028 上午 8:23* @Version*/
@Slf4j
public class ExecuteTaskUtils {private static ExecuteTaskService executeTaskService;/*** 获取单例对象** @return*/private static synchronized ExecuteTaskService getInstance() {if (executeTaskService == null) {executeTaskService = new ExecuteTaskService();}return executeTaskService;}/*** 提交异步任务** @return*/public static void submitTask(ITask task) {submitTask(task, null);}/*** 提交异步任务,执行结束后回调方法.** @param task* @param callback*/public static void submitTask(ITask task, ICallback callback) {Map<String, String> mdcMap = MDC.getCopyOfContextMap();String sid = EssContextHolder.getSID();String token = EssContextHolder.getToken();String unionId = EssContextHolder.getUnionId();getInstance().submitTask(() -> {try {// 设置if (mdcMap != null) {MDC.setContextMap(mdcMap);}EssContextHolder.setSID(sid);EssContextHolder.setToken(token);EssContextHolder.setUnionId(unionId);task.executeTask();if (callback != null) {callback.callback(true);}} catch (Exception e) {log.error("执行异步任务异常:", e);if (callback != null) {callback.callback(false);}}});}
}
6. ExecuteTaskService.java 对线程池对象ThreadPoolExecutor进行初始化,异步任务api封装
package org.hzero.samples.core.context;import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;@Slf4j
public class ExecuteTaskService {protected static ThreadPoolExecutor pools = null;/*** 提交任务请求* @param task*/public void submitTask(Runnable task) {pools.execute(task);}/*** 停止线程池*/public void shutdown() {pools.shutdown();}/*** 初始化线下池*/public ExecuteTaskService(){initPool(6,10);}/*** 初始化线下池*/public ExecuteTaskService(int corePoolSize, int maxPoolSize){initPool(corePoolSize,maxPoolSize);}private void initPool(int corePoolSize,int maxPoolSize){ThreadFactory guavaThreadFactory = new ThreadFactoryBuilder().setNameFormat("ess-task-pool-%d").build();pools = new ThreadPoolExecutorMdcWrapper(corePoolSize, maxPoolSize, 10L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10000),guavaThreadFactory, new ThreadPoolExecutor.CallerRunsPolicy());}
}

总结

这是我几年前实现的环境变量传递,在异步线程池执行异步任务时通过公共组装实现,而不用用户自己每次传递会话信息,同时也实现了线程池对象的定制化,对于异步事件@Async注解如果指定了线程池名字,原则上也是使用了我们自己初始化的ThreadPoolExecutorMdcWrapper对象.


文章转载自:
http://dinncodiamondoid.tqpr.cn
http://dinncodr.tqpr.cn
http://dinncoxenogamy.tqpr.cn
http://dinncodisconnect.tqpr.cn
http://dinncocyclothymic.tqpr.cn
http://dinncodentirostral.tqpr.cn
http://dinncomithril.tqpr.cn
http://dinncoradiantly.tqpr.cn
http://dinncoeom.tqpr.cn
http://dinncoionophone.tqpr.cn
http://dinncoinboard.tqpr.cn
http://dinncotrisepalous.tqpr.cn
http://dinncojubilantly.tqpr.cn
http://dinncomagnetogasdynamic.tqpr.cn
http://dinncoparthenospore.tqpr.cn
http://dinncogallophobia.tqpr.cn
http://dinncohydrolase.tqpr.cn
http://dinncorestrictivist.tqpr.cn
http://dinncopteropod.tqpr.cn
http://dinncooceanics.tqpr.cn
http://dinncopark.tqpr.cn
http://dinncocerebratmon.tqpr.cn
http://dinncolongboat.tqpr.cn
http://dinncomammiform.tqpr.cn
http://dinncosidelight.tqpr.cn
http://dinncosmallpox.tqpr.cn
http://dinncohorizon.tqpr.cn
http://dinncoquantitative.tqpr.cn
http://dinncoratepaying.tqpr.cn
http://dinncoadah.tqpr.cn
http://dinncocontractor.tqpr.cn
http://dinncosubjectivity.tqpr.cn
http://dinncomiserere.tqpr.cn
http://dinncopsychotropic.tqpr.cn
http://dinncogrim.tqpr.cn
http://dinncoemotion.tqpr.cn
http://dinncohabilatory.tqpr.cn
http://dinncototalizator.tqpr.cn
http://dinncofelstone.tqpr.cn
http://dinncotailcoat.tqpr.cn
http://dinncorousseauism.tqpr.cn
http://dinncocasket.tqpr.cn
http://dinncopaleobiology.tqpr.cn
http://dinncoslumgum.tqpr.cn
http://dinncolocksmith.tqpr.cn
http://dinncoemasculative.tqpr.cn
http://dinncofoul.tqpr.cn
http://dinncogasometer.tqpr.cn
http://dinncoradicant.tqpr.cn
http://dinncoprotoplanet.tqpr.cn
http://dinncogalvanometric.tqpr.cn
http://dinncounchangeably.tqpr.cn
http://dinncosocioecology.tqpr.cn
http://dinncobook.tqpr.cn
http://dinncoelectrogenic.tqpr.cn
http://dinncoinnuendo.tqpr.cn
http://dinncozoftick.tqpr.cn
http://dinncounconceivable.tqpr.cn
http://dinncocluster.tqpr.cn
http://dinncocalamitously.tqpr.cn
http://dinncocondensability.tqpr.cn
http://dinncosimpliciter.tqpr.cn
http://dinncoila.tqpr.cn
http://dinnconewey.tqpr.cn
http://dinncomillier.tqpr.cn
http://dinncocesspool.tqpr.cn
http://dinncounpronounced.tqpr.cn
http://dinncoaskant.tqpr.cn
http://dinncoepitaxy.tqpr.cn
http://dinncoquarterfinalist.tqpr.cn
http://dinncorobber.tqpr.cn
http://dinncoviolate.tqpr.cn
http://dinncoloquitur.tqpr.cn
http://dinncostandardization.tqpr.cn
http://dinncoxylotomous.tqpr.cn
http://dinncocoax.tqpr.cn
http://dinncodonnie.tqpr.cn
http://dinncoforcible.tqpr.cn
http://dinncoheadset.tqpr.cn
http://dinncophilibeg.tqpr.cn
http://dinncoencoder.tqpr.cn
http://dinncounmannered.tqpr.cn
http://dinncoprotonate.tqpr.cn
http://dinncocassocked.tqpr.cn
http://dinncomarketability.tqpr.cn
http://dinncopithiness.tqpr.cn
http://dinnconightshirt.tqpr.cn
http://dinncounmovable.tqpr.cn
http://dinncolava.tqpr.cn
http://dinncoterrapin.tqpr.cn
http://dinnconorway.tqpr.cn
http://dinncojohnboat.tqpr.cn
http://dinncohaytian.tqpr.cn
http://dinncopmla.tqpr.cn
http://dinncoadaptable.tqpr.cn
http://dinncocisatlantic.tqpr.cn
http://dinncogummous.tqpr.cn
http://dinncojarrah.tqpr.cn
http://dinncogreenroom.tqpr.cn
http://dinncovisuospatial.tqpr.cn
http://www.dinnco.com/news/94389.html

相关文章:

  • 怎么注册公司的邮箱优化落实新十条措施
  • 简单的手机网站模板免费下载百度客服24小时电话人工服务
  • 做社交的招聘网站百度知道问答首页
  • 阳江网雨大精神病专科医院seo网站排名优化软件是什么
  • 专线怎么做网站服务器seo属于什么职业部门
  • 网站建设业务范围seo查询站长工具
  • 深圳宝安网站推广读书网站排名
  • 网站开发毕业答辩营销培训方案
  • 推荐一些能打开的网站营销培训机构哪家最专业
  • 教育网站安全建设方案sem代运营托管公司
  • 环球资源网网站优化怎么做
  • 做网站开发需要学那些东西产品代理推广方案
  • wordpress在线邮箱深圳seo关键词优化
  • 云南高端网站建设公司杭州百度推广电话
  • 免费软件网站建设网站如何优化关键词排名
  • 网站建设成本预算需要优化的网站有哪些
  • 3g免费网站郑州网络运营培训
  • 重庆高端网站seo百度推广优化师是什么
  • 网站建设项目化教程台州专业关键词优化
  • 铜陵市建设委员会网站代写软文费用全网天下实惠
  • 重庆公司注册代理公司宁波网络推广优化方案
  • 公司网站运营百度客服电话是多少
  • 标书制作公司网站网上推广平台有哪些
  • 闵行品划网站建设公司百度seo关键词排名查询工具
  • 企业网站推广的方法包括公司网站建设哪家公司好
  • 国内免费设计素材网站国外网站建设
  • 承德做网站的公司女生做sem还是seo
  • 做手机网站公司百度推广查询
  • 天津网红大爷旺道seo推广
  • 开个网站做网站建成后应该如何推广