Fork of Paper 將區域化多執行緒新增至專用伺服器。
Folia 將附近載入的區塊分組以形成「獨立區域」。有關 Folia 如何對附近區塊進行分組的確切詳細信息,請參閱 PaperMC 文件。每個獨立區域都有自己的滴答循環,以常規 Minecraft 滴答率 (20TPS) 滴答。滴答循環在執行緒池上並行執行。不再有主線程,因為每個區域實際上都有自己的「主線程」來執行整個滴答循環。
對於具有許多分散玩家的伺服器,Folia 將創建許多分散區域並在可配置大小的線程池上並行勾選它們。因此,Folia 應該能夠很好地適應這樣的伺服器。
Folia也是它自己的項目,在可預見的將來不會合併到Paper中。
更詳細但抽象的概述:項目概述。
自然分散玩家的伺服器類型,如 skyblock 或 SMP,將從 Folia 中受益最多。伺服器也應該有相當多的玩家數量。
理想情況下,至少 16 個核心(不是執行緒)。
首先,建議預先產生世界,這樣可以大幅減少所需的區塊系統工作執行緒的數量。
以下是基於 Folia 發布之前在我們運行的測試伺服器上所做的測試(峰值約為 330 名玩家)的非常粗略的估計。因此,它並不準確,需要進一步調整 - 只是將其作為起點。
應考慮機器上可用核心的總數。然後,為以下物件分配線程:
-XX:ConcGCThreads=n
標誌實現的。不要將此標誌與-XX:ParallelGCThreads=n
混淆,因為並行 GC 執行緒僅在應用程式被 GC 暫停時運行,因此不應考慮在內。完成所有分配後,系統上的剩餘核心直到 80% 分配(分配的總線程數 < 可用 cpu 的 80%)可以分配給tickthreads(在全域配置下,threaded-regions.threads)。
您不應分配超過 80% 的核心的原因是插件甚至伺服器可能會使用您無法設定甚至預測的其他執行緒。
此外,以上都是基於玩家數量的粗略猜測,但線程分配很可能並不理想,您需要根據最終看到的線程的使用情況來調整它。
沒有更多的主線。我希望現有的每個插件都需要一定程度的修改才能在 Folia 中運作。此外,任何類型的多執行緒都會在插件保存的資料中引入可能的競爭條件 - 因此,必然需要進行更改。
因此,請將您對相容性的期望設為 0。
目前,有許多API依賴主執行緒。我預計與 Paper 相容的插件基本上為零,與 Folia 相容。不過,我們計劃添加 API,使 Folia 外掛程式與 Paper 相容。
例如,Bukkit 調度程式。 Bukkit Scheduler 本質上依賴單一主執行緒。 Folia 的 RegionScheduler 和 Folia 的 EntityScheduler 允許將任務調度到「擁有」位置或實體的任何區域的「下一個刻度」。這些可以在常規 Paper 上實現,除了它們調度到主執行緒 - 在這兩種情況下,任務的執行將發生在「擁有」位置或實體的執行緒上。這個概念普遍適用,因為目前的論文(單線程)可以被視為一個巨大的“區域”,涵蓋了所有世界中的所有區塊。
目前尚未決定是直接將該 API 新增到 Paper 本身還是新增到 Paperlib。
首先,Folia 破壞了許多插件。為了幫助使用者確定哪些外掛程式可以運作,只有作者明確標記為可與 Folia 配合使用的插件才會被載入。透過將「folia-supported: true」放入插件的plugin.yml中,插件作者可以將其外掛程式標記為與區域化多執行緒相容。
另一個重要的規則是這些區域是並行運行的,而不是同時運行的。他們不共享數據,也不期望共享數據,而共享數據會導致數據損壞。在任何情況下在一個區域中運行的程式碼都不能存取或修改另一個區域中的資料。僅僅因為多線程就在名稱中,並不意味著現在一切都是線程安全的。事實上,只有少數東西是線程安全的才能實現這一點。隨著時間的推移,線程上下文檢查的數量只會增加,即使它會帶來效能損失 -沒有人會使用或開發一個有很多錯誤的伺服器平台,而防止和發現這些錯誤的唯一方法bugs 的目的是在錯誤存取的根源處使錯誤存取難以失敗。
這意味著 Folia 相容外掛程式需要利用 RegionScheduler 和 EntityScheduler 等 API 來確保其程式碼在正確的執行緒上下文上運行。
一般來說,可以安全地假設一個區域擁有來自事件來源的大約 8 個區塊中的區塊資料(即玩家破壞區塊,可能可以存取該區塊周圍的 8 個區塊)。但是,這並不能得到保證 - 插件應該利用即將推出的線程檢查 API 來確保正確的行為。
線程安全的唯一保證來自這樣一個事實:單個區域擁有某些區塊中的資料 - 如果該區域正在運行,則它可以完全存取該資料。該數據具體是實體/區塊/poi 數據,與任何插件數據完全無關。
正常的多執行緒規則適用於外掛程式儲存/存取自己的資料或其他外掛程式的資料 - 事件/命令/等。被並行調用,因為區域是並行滴答的(我們不能以同步方式調用它們,因為這會導致死鎖問題並會影響效能)。沒有簡單的方法可以解決這個問題,這完全取決於正在存取的資料。有時並發集合(如 ConcurrentHashMap)就足夠了,但通常不小心使用並發集合只會隱藏線程問題,幾乎無法調試。
要正確理解 API 添加,請閱讀項目概述。
要正確理解 API 添加,請閱讀項目概述。
一般經驗法則:
在擁有實體/玩家的區域上呼叫實體/玩家的命令。控制台命令在全域區域上執行。
涉及單一實體的事件(即玩家打破/放置方塊)在區域擁有實體上呼叫。涉及實體操作的事件(例如實體損壞)在擁有目標實體的區域上呼叫。
事件的 async 修飾符已被棄用 - 從區域或全域區域觸發的所有事件都被視為synchronous ,即使不再有主執行緒。
< repository >
< id >papermc</ id >
< url >https://repo.papermc.io/repository/maven-public/</ url >
</ repository >
< dependency >
< groupId >dev.folia</ groupId >
< artifactId >folia-api</ artifactId >
< version >1.20.1-R0.1-SNAPSHOT</ version >
< scope >provided</ scope >
</ dependency >
PATCHES-LICENSE 檔案描述了 api 和伺服器修補程式的許可證,除非另有說明,可在./patches
及其子目錄中找到。
這個分叉基於此處找到的 PaperMC 分叉範例。因此,它包含在該專案中對其進行的修改,請參閱儲存庫以取得修改文件的許可證資訊。