1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

2021.04.30 异步线程优化用户体验

背景

对于后端开发,接口响应时长是一个很关键的点,它不仅体现了你写的接口的性能,同时也代表着用户体验,如果你的内容响应时间过长,用户可能早就把网页关闭了。

互联网行业,有一个用户体验原则——2/5/10秒原则。

就是说,在2秒之内给客户响应被用户认为是“非常有吸引力”的用户体验。

在5秒之内响应客户被认为“比较不错”的用户体验,在10秒内给用户响应被认为“糟糕”的用户体验。

如果超过10秒还没有得到响应,那么大多用户会认为这次请求是失败的。

所以很多互联网企业,接口发布上线前,都有一个压测要求:特定并发量下,接口的响应时间不能大于200ms

在这样的要求之下,想要提升接口性能,减少用户等待时间,将部分非实时、不重要、确定无异常等交易(比如订单处理、办理完某个业务给用户发消息等),设计成异步处理的方式是一个不错的选则,今天我们就来通过一个简单的示例演示,来了解下异步交易如何实现。

异步交易演示

假设,我们有这样的业务需求:

场景一: 我们有一个教务管理系统,讲师导入创建了一门新的课程,并制定了学员,处理课程创建的操作外,我们还需要在课程创建成功后,给学员发消息。但是发消息并非是特别重要的操作,这时候我们就可以通过异步交易来发送消息。

场景二:我们需要在用户注册成功后,给用户发送消息(邮件或短信)通知用户,和场景一类似,发送消息非必须业务,为了提升系统响应效率,这时候异步交易是个不错的选择。

场景说完了,下来看我们的简单应用:

我们先创建了一个线程池:

private static ThreadPoolExecutor threadPoolExecutor =
            new ThreadPoolExecutor(5, 10, 1,
                    TimeUnit.SECONDS, new LinkedBlockingQueue<>(5));

然后,我们在核心交易的最后,通过线程池的submit启动了一个线程:

 threadPoolExecutor.submit(() -> this.sendMessage(messageList));

通过这个线程去执行发消息的操作,这里我们用到了lamubda表达式,上面的代码等同于:

threadPoolExecutor.submit(new Runnable() {
            @Override
            public void run() {
                sendMessage(messageList);
            }
        });

下面是完整代码:

/**
 * @author syske
 * @date 2021-05-01 9:34
 */
public class Example {
    private static ThreadPoolExecutor threadPoolExecutor =
            new ThreadPoolExecutor(5, 10, 1,
                    TimeUnit.SECONDS, new LinkedBlockingQueue<>(5));
    /**
     * 发送消息
     * @param messageList 消息列表
     * @return
     */
    public AtomicInteger sendMessage(List<String> messageList) {
        AtomicInteger successCount = new AtomicInteger();
        messageList.forEach(m -> {
            System.out.println("发送消息:" + m);
            successCount.getAndIncrement();
        });
        return successCount;
    }

    /**
     * 核心业务处理
     * @return
     */
    public String deal() {
        List<String> messageList = new ArrayList<>();
        // doSomeThing() 其他业务处理
        System.out.println("开始组装消息~Start");
        for (int i = 0; i < 1000; i++) {
            int randomInt1 = new Random().nextInt();
            messageList.add("发送数字信息:" + randomInt1);
        }
        System.out.println("组装消息完成~End");
        System.out.println("开始发送消息~Start");
        threadPoolExecutor.submit(() -> this.sendMessage(messageList));
        System.out.println("发送消息完成~End");
        return "业务处理完成";
    }

    public static void main(String[] args) {
        Example example = new Example();
        String result = example.deal();
        System.out.println(result);
        threadPoolExecutor.shutdown();
    }
}

执行上面的方法,你会发现,核心业务方法在消息没发送就已经返回了:

开始组装消息~Start
组装消息完成~End
开始发送消息~Start
发送消息完成~End
业务处理完成
发送消息:发送数字信息:-123158837
……
……
发送消息:发送数字信息:-1354635036

这样我们的异步交易就实现了,是不是很简单呀,如果你的异步业务是有返回值的,那在启动线程的时候,你可以通过Callable来实现,它和Runnable没有本质区别,只是它是可以有返回值的。

总结

其实今天的内容很简单,实现过程也很容易,异步交易中真正难的是如何拆分你的业务,这就需要你自己多思考,多实践,多总结了,还是那句话会用这个工具很简单,但清楚什么时候用这个工具才更重要。好了,各位小伙伴节日快乐,好好享受假期,但也别忘了学习哦

项目路径:

https://github.com/Syske/example-everyday

本项目会持续每日更新,让我们一起学习,一起进步,遇见更好的自己,加油呀

posted @ 2021-05-01 11:01  云中志  阅读(66)  评论(0编辑  收藏  举报