搜了一下,如果是传统的那种基于线程+阻塞IO的方式,有配置参数可以控制最大线程并发数量,另外还有线程池的做法. 参见: Spring @Async limit number of threads

如果是非阻塞IO的做法,需要使用 Spring 5. 一种是 Spring MVC (Servlet)模式, 另一种是 Spring WebFlux模式.

参见 Understanding Spring Reactive: Servlet 3.1/Spring MVC Non-Blocking IO

Understanding Spring Reactive: Introducing Spring WebFlux

一文带你了解Spring 5.0 WebFlux应用场景

Java Mono, Flux相关知识: Java反应式框架Reactor中的Mono和Flux

Webflux中可以用WebClient异步发起对其他服务的请求: Spring5 Webflux之Webclient使用

Java里的Promise: CompletableFuture. 参见Promise

Promise回调的写法和Mono很像, 但是Java Promise是可以有Async/Await的. 例如: Async Await in Java. 可以尝试 electronicarts/ea-async

那Mono是否也可以有async/await呢?

看这种链式调用, 脑壳痛: How do I wait for a List to get resolved?

也许…换门语言, 比如Kotlin里的Corotine就很棒!

Kotlin的异步编程(基于协程): Asynchronous programming techniques

但很可惜,Java编译器不支持这种操作,所以在不动bytecode/编译链的情况下,基本上没可能在Java里实现协程了。Can I take advantage of Kotlin’s Coroutines by using them in Java code?

老三样

HMCL 启动器

BlessingSkinServer, 推荐使用 LiteServer Project皮肤站

authlib-injector 登录验证

服务端

Arclight

支持MC 1.16.5和高版本Forge (36.2.0+). 目前看和一些mod之间有冲突. 但仍属于比较好的选择.

Mohist

支持MC 1.16.5, 但历史上曾有过再发布和未经告知即删除mod的举动, 有较大安全隐患.

LoliServer

支持MC 1.16.5. 但没能成功安装, 排查是从loliserver指定的服务器下载资源文件失败.

运行时

AdoptOpenJDK 11 LTS / 16

NodeJS 14 LTS / 16

或者使用面板 (镜像中已包含推荐的环境):

LiteServerProject/MCSManager

Podman

服务端插件

EssentialsX 常用命令 (tpa, home, back等)

LuckPerms 权限管理

Vault 经济前置插件

BanItem 禁用物品

ServerRestorer 服务器自动备份

Tips

禁用Mod版本检查缩短启动时间

修改 .minecraft/config/fml.toml 文件, 将 versionCheck 设为 false.

注: 某些mod可能内置了版本更新检测/赞助者列表拉取逻辑, 这些是不能通过此项设置关闭的.

1
2
3
4
5
6
7
# Enable forge global version checking
versionCheck = false
# does the splashscreen run
splashscreen = true
defaultConfigPath = "defaultconfigs"
# max threads for parallel loading : -1 uses Runtime#availableProcessors
maxThreads = -1

祖传启动参数

参考 JVM Tuning: Optimized G1GC for Minecraft - Aikar’s Thoughts

1
2
3
#!/bin/bash
java -Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -javaagent:authlib-injector-1.1.38.jar=https://mc.kiritow.com/api/yggdrasil -jar arclight-forge-1.16.5-1.0.20.jar nogui

参考 https://git-scm.com/docs/partial-clone

git clone --depth 1这样的浅拷贝方案不同, partial clone可以做到获取某次提交中只与某个文件子树相关的提交内容. 大部分场景下应该都用不到这种功能, 一般都是那种Monorepo(Monolithic repository)因为把所有项目都放到同一个仓库的不同文件夹下才有的特殊需求.

查看符合某个模式的索引, 输出标头, 并按照索引大小倒序排列. 参考 cat indices API

1
GET _cat/indices/some-*20210806*?v&s=ss:desc

查看某个索引的设置

1
GET /some-index-20210806/_settings

查看符合某个模式的模板设置

1
GET _template/some-index-*

查看某个索引下分片的分布情况, 输出表头.

1
GET _cat/shards/some-index-20210806?v

查看集群设置

1
GET /_cluster/settings

查看集群中正在进行的任务. 例如reindex

1
GET /_tasks?detailed=true&actions=*reindex

终止集群中某个正在进行的任务,根据上一条中查到的任务ID. 参考:Task Management API

1
POST _tasks/nodeID:taskID/_cancel

删除某个索引

1
DELETE /some-index-20210806

调整某个模板设置(举例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
PUT /_template/some-template-1
{
"order": 9,
"index_patterns": [
"some-index-*"
],
"settings": {
"index": {
"number_of_shards": "30",
"routing": {
"allocation": {
"include": {
"temperature": "hot"
},
"require": {
"temperature": "hot"
}
}
}
}
},
"mappings": {
"doc": {
"dynamic_templates": [
{
"message_field": {
"path_match": "message",
"mapping": {
"norms": false,
"type": "text"
},
"match_mapping_type": "string"
}
},
{
"string_fields": {
"mapping": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"match_mapping_type": "string",
"match": "*"
}
}
],
"date_detection": false,
"properties": {
"@timestamp": {
"type": "date"
},
"@version": {
"type": "keyword"
}
}
}
},
"aliases": {}
}

⚡萨 日 朗!!!⚡]

⚡️喝了105杯核废水⚡️

【原曲不使用】鲜烈之龙

鲜烈之龙啊啊啊

鲜烈的萨日朗

【原曲不使用】加州旅馆

急 急 喵 内 令

【东方】朝你大吉猫咪捏一把

【东方】飘上月球,不死乒乓

【东方】欲望煤气灶

253原曲 東方心綺楼 「塵界不変のペシミズム&心綺楼囃子」

【東方原曲】 東方神霊廟 4面道中BGM - デザイアドライブ

沙丁鱼从地面钻了出来

【假装单曲14】我站在东北望北京-完整纯享版

恶 臭 电 音

酒醉的蝴♂蝶

幕府时期宽带广告 稀 有 影 像

往期优秀作品推荐

2019年
2018年
2017年

4月8日推荐

Caravan Palace - Lone Digger 【网易云音乐

3月5日推荐

新宝島 - サカナクション 【网易云音乐】【B站Vtuber版本】【B站原版

1月23日推荐

神のまにまに (神的随波逐流) 【网易云音乐

Little Swing - AronChupa / Little Sis Nora 【网易云音乐

I’m an Albatraoz - AronChupa 【网易云音乐

天才白痴钱钱钱 - 许冠杰 【网易云音乐

【Giao哥】That Giao - 小可儿 【B站

【DNF】欧皇 - 小巨人猪大星 【B站

唱了一下”马口铁之舞” - MiraiAkari【B站】【Youtube

虎视眈眈 - Mirai Akari 【B站】【Youtube

9月24日推荐

Martin Garrix & Justin Mylo - Burn Out (Official Video) feat. Dewain Whitmore 【Youtube】 【网易云音乐

Alan Walker - Darkside (feat. Au/Ra and Tomine Harket) 【Youtube】【网易云音乐

Alan Walker - All Falls Down (feat. Noah Cyrus with Digital Farm Animals) 【Youtube

DOCTOR VOX - Neon Lights [Royalty Free Music] 黑镖客梦回视频BGM【Youtube】 【SoundCloud】 【网易云音乐(电台)】【黑镖客梦回 (B站)】【黑镖客梦回 (Youtube)

V-Pop - Lindsey Stirling 【网易云音乐

回レ! 雪月花 【网易云音乐

白金ディスコ 【网易云音乐

光るなら 【网易云音乐

The Nights (Original Mix) - Avicii【网易云音乐

Against the Sun (feat. Anna Yvette) - Rootkit【网易云音乐

Intro -The xx【网易云音乐

The Lights - Panda Eyes 【网易云音乐

Beast - Vicetone / Nico Vega 【网易云音乐

Blank - Disfigure【网易云音乐

In Motion - CMA 【网易云音乐

Felt Like You (Nebbra Sourz Remix) - Manotett 【网易云音乐

You Make Me Go (Original Mix) - Insan3Lik3 【网易云音乐

Colors - Hardwell / Andreas Moe / Tiësto 【网易云音乐

Tomorrow’s Another Day - CMA 【网易云音乐

Vulnerability - MitiS 【网易云音乐

The Edge - Electro-Light / Kathryn MacLean 【网易云音乐

August Song - Janji / T.R. 【网易云音乐

Sugarless GiRL - CAPSULE 【网易云音乐

Indigo - Subtact 【网易云音乐

Beyond The Moon - A.M.R. / 武川アイ 【网易云音乐

Truth - Tristam 【网易云音乐

A Dream - Rundfunk 【网易云音乐

Fire Inside (Skrux Rework) - Mr FijiWiji 【网易云音乐

Who We Are - Luigi Lusini 【网易云音乐

Whispers (Radio Edit) - Ana Criado 【网易云音乐

Sanctuary - Gareth Emery 【网易云音乐

Howl At The Moon (Original Mix) - Stadiumx / Taylr Renee 【网易云音乐

One Third - Mendum 【网易云音乐

Sunlight - JJD / AudioBlade 【网易云音乐

Altostratus (Original Mix) - syatten 【网易云音乐

Feet On The Ground (Original Mix) - Nicky Romero / Anouk 【网易云音乐

Skydiving (In5um Remix) - remix - James Woods 【网易云音乐

Masked Heroes - Vexento 【网易云音乐

Don’t Stop (TheFatRat Remix) - TheFatRat 【网易云音乐

Landvetter - Moonlit Sailor 【网易云音乐

Waiting (for the End) - Marco V / Maruja Retana 【网易云音乐

Sentient - Mr FijiWiji / Tülpa 【网易云音乐

Evolution - Teminite 【网易云音乐

The Alphabeat - David Guetta 【网易云音乐

Something New - Faul 【网易云音乐

Resurrection of the Dagger - Varien 【网易云音乐

Timeless (radio edit) - Wildstylez 【网易云音乐

从今年2月中旬开始一直在看《Learning Python》这本书,现在看到了第四部分。感觉这本书讲的很详细,有点像在认真学习语言的那种感觉。不过总感觉时间不够用,感觉自己不再是naive的学生了…

  • Python使用#作为注释,没有语法上的多行注释,但是可以通过【长字符串】把脚本变成字符串。即在开头结尾分别加上'''

  • Python2里print是语句,Python3里是函数

  • Python里所有变量本质上都是引用,包括数字和字符串变量。

  • 在常见类型中,数字、字符串是不可变的对象。对字符串或数字进行的操作会生成一个新的对象,并返回其引用。因此,python中不存在a++这样的语法。

  • Python中的字符串格式化为:

    1
    2
    "Good {}, Mr. {}".format("Morning","Kirito")
    "{1} and {0} are good friends.".format("Kim","Trump")
  • True和False只是1和0,即True==1或者False==0的结果都是True。所有空的容器都是False。

  • list()是列表, dict()是字典(即C++里面的map或者lua里的table)

  • 列表解析

    1
    2
    3
    4
    5
    6
    7
    8
    lst=[x for x in range(10)] # also lst=list(range(10))
    print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    lst=[x**2 for x in range(10)] # pow(x,2)
    print(lst) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

    lst=[x**2 for x in range(10) if x%2==1] # with condition
    print(lst) # [1, 9, 25, 49, 81]
  • 列表分片

    1
    2
    3
    lst=[x**2 for x in range(10)]
    print(lst[0:3]) # [0, 1, 4]
    print(lst[1:8]) # [1, 4, 9, 16, 25, 36, 49]

    列表分片会产生一个新列表,对新列表增删不会影响到原列表,但是新列表中的引用仍然和旧列表中相同。这意味着如果通过新列表中成员引用修改值,会影响到旧列表中对应引用的值。(相当于修改了指针的地址空间实际内容,从而让所有指针读出来的内容看起来都被修改了)

  • 列表分片赋值

    1
    2
    3
    lst=[x**2 for x in range(10)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    lst[1:3]=['?','x','y','z']
    print(lst) # [0, '?', 'x', 'y', 'z', 9, 16, 25, 36, 49, 64, 81]

    相当于lst[1:3]被删除后在此处填入右侧的列表

  • Python3中除法 / 会尽可能产生小数,使用整除法 // 来产生整数。

  • Python通过缩进区分代码块. 在每个切换缩进开始的语句经常会附带冒号:. 例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    while True:
    pass

    def func(a,b):
    raise Exception("Ahh... are you ok?")

    if True:
    pass
    elif False:
    pass
    else:
    pass

    try:
    func(1,2)
    except Exception as e:
    print("Exception: {}".format(e))
    except:
    print("Unexcepted!")
    else:
    print("Nothing happened.")
    finally:
    print("Oh you will do this.")
  • Python函数参数可以附带默认值,传入参数时可使用形参变量名指定

    1
    2
    3
    4
    5
    6
    7
    def someFunc(a,b,name=None,place=None):
    print(a,b,name,place)

    someFunc(1,2,name="God",place="Haven")
    someFunc(1,2,name="nobody")
    someFunc(1,2,place="nowhere")
    someFunc(1,2)

    某种意义上,也可以传入足够数量的参数对someFunc进行调用而不写明变量对应关系,但这是不推荐的。

  • 三目运算符

    1
    "I love you" if YouLoveMe() else "I hate you"