Tomcat Cluster 複製 Session 時,會將其中的對象實例一併複製,前提是對象實作 java.io.Serializable。Tomcat 並非直接序列化 HashMap,而是逐一讀取屬性並單獨序列化,確保對象圖完整復制。
protected void writeObject(ObjectOutputStream stream) throws IOException {
// 寫入標量屬性:creationTime, lastAccessedTime, maxInactiveInterval, isNew, isValid, thisAccessedTime, id
// 收集可序列化屬性
String keys[] = keys();
ArrayList saveNames = new ArrayList();
ArrayList saveValues = new ArrayList();
for (int i = 0; i < keys.length; i++) {
Object value = attributes.get(keys[i]);
if (value instanceof Serializable) {
saveNames.add(keys[i]);
saveValues.add(value);
}
}
// 寫入屬性數量及每個屬性
stream.writeObject(new Integer(saveNames.size()));
for (int i = 0; i < saveNames.size(); i++) {
stream.writeObject(saveNames.get(i)); // key
try {
stream.writeObject(saveValues.get(i)); // value 逐個序列化
} catch (NotSerializableException e) {
stream.writeObject(NOT_SERIALIZED); // 標記不可序列化
}
}
}
對比 HashMap.writeObject() 直接寫入 key-value 交替流,Tomcat 額外過濾不可序列化對象,避免整個 Session 序列化失敗。
同步 Session 開銷在同一局域網極小,遠小於帶來的橫向擴展收益。幾台工作站間的網路延遲可忽略不計。