php伺服器怎麼集群,伺服器怎麼運行php

本文目錄一覽:

PHPCMS能不能做成多台伺服器集群?

其實這些都可以實現,當時設計的時候就考慮了單獨的圖片伺服器的需求,但是如果真要操作需要修改部分程序,但不需要像樓上說的那樣修改架構!不過三個伺服器可以前端為一個squid的方式,這樣靜態頁面都在前端減少對於程序伺服器的壓力。還可以通過rsync把附件文件傳送到其他伺服器,然後修改UPLOAD_URL來使圖片地址改為另外一台伺服器

如何實現php+session+memcached高可用集群

在這個互聯網高度發達的時代,許多應用的用戶動輒成百上千萬,甚至上億。為了支持海量用戶的訪問,應用伺服器集群這種水平擴展的方式是最常用的。這種情形下,就會涉及到許多單機環境下完全不需要考慮的問題,這其中session的創建、共享和存儲是最常見之一。

在單機環境中,Session的創建和存儲都是由同一個應用伺服器實例來完成,而存儲也僅是內存中,最多會在正常的停止伺服器的時候,把當前活動的Session鈍化到本地,再次啟動時重新載入。

而多個實例之間,Session數據是完全隔離的。而為了實現Session的高可用,多實例間數據共享是必然的,下面我們以Redis 的SessionManager實現多Tomcat實例Session共享的配置為例,我們來梳理下一般session共享的流程:

添加具體要使用的manager的Jar文件及其依賴

redis session manager依賴jedis, commons-pool, commons-pool2

對應版本的redis session manager的jar文件

在TOMCAT_HOME/conf/context.xml中增加如下配置

Valve className=”com.radiadesign.catalina.session.RedisSessionHandlerValve” /

Manager className=”com.radiadesign.catalina.session.RedisSessionManager”

host=”localhost”

port=”6379″ database=”0″

maxInactiveInterval=”30″ /

其中host和port等替換為對應的配置信息

啟動多個Tomcat實例,以自帶的examples應用為例進行驗證

訪問examples應用的servlets/servlet/SessionExample,

在頁面中添加數據到session中,並查看頁面上對應的session信息

訪問另一個實例上相同應用的頁面,查看session信息,兩者應該是一致的

使用redis-cli查看redis中存儲的對應數據,相應的sessionId對應的數據已經保存了下來

以上是一個基本的配置過程,而在這些配置與驗證的步驟中,第二步是核心邏輯實現。 前面的文章,曾介紹過Tomcat的Valve,在請求處理時,Pipeline中的各個Valve的invoke方法會依次執行。Tomcat的AccessLogValve介紹

此處的session處理,就是以一個自定義Valve的形式進行的。關於Session的文章,前面也寫過幾篇,會附在結尾處。

以下是RedisSessionhandlerValve的invoke方法,我們看,主要是在Valve執行後進行Session的存儲或移除。

public void invoke(Request request, Response response) {

try {

getNext().invoke(request, response);

} finally {

final Session session = request.getSessionInternal(false);

storeOrRemoveSession(session);

manager.afterRequest();

}

}

而session的保存和移除又是通過manager執行的。 manager.save(session); manager.remove(session);

這裡,manager就是前面定義的RedisSessionManager。默認單實例情況下,我們使用的都是StandardManager,對比一下兩者,標準的Manager對於session的創建和刪除,都會調到其父類ManagerBase中相應的方法,

public void add(Session session) {

sessions.put(session.getIdInternal(), session);

int size = getActiveSessions();

if( size maxActive ) {

synchronized(maxActiveUpdateLock) {

if( size maxActive ) {

maxActive = size;

}

}

}

}

public void remove(Session session, boolean update) {

if (session.getIdInternal() != null) {

sessions.remove(session.getIdInternal());

}

}

我們來看,由於其只保存在內存的Map中protected MapString, Session sessions = new

ConcurrentHashMap(),每個Tomcat實例都對於不同的map,多個實例間無法共享數據。

對應到RedisSessionManager對於session的處理,都是直接操作redis,基本代碼是下面這個樣:

public void save(Session session) throws IOException {

Jedis jedis = null;

Boolean error = true;

try {

RedisSession redisSession = (RedisSession) session;

Boolean sessionIsDirty = redisSession.isDirty();

redisSession.resetDirtyTracking();

byte[] binaryId = redisSession.getId().getBytes();

jedis = acquireConnection();

if (sessionIsDirty || currentSessionIsPersisted.get() != true) {

jedis.set(binaryId, serializer.serializeFrom(redisSession));

}

currentSessionIsPersisted.set(true);

jedis.expire(binaryId, getMaxInactiveInterval());

} }

移除時的操作是這樣的

public void remove(Session session, boolean update) {

Jedis jedis = null;

Boolean error = true;

log.trace(“Removing session ID : ” + session.getId());

try {

jedis = acquireConnection();

jedis.del(session.getId());

error = false;

} finally {

if (jedis != null) {

returnConnection(jedis, error);

}

}

}

而此時,多個Tomcat實例都讀取相同的Redis,session數據是共享的,其它實例的初始請求過來時,由於會執行findSession的操作,此時會從Redis中載入session,

public Session findSession(String id) throws IOException {

RedisSession session;

if (id == null) {

session = null;

currentSessionIsPersisted.set(false);

} else if (id.equals(currentSessionId.get())) {

session = currentSession.get();

} else {

session = loadSessionFromRedis(id); // 看這裡,會從redis中load

if (session != null) {

currentSessionIsPersisted.set(true);

}

}

currentSession.set(session);

currentSessionId.set(id);

return session;

}

從而可以保證在一個實例被切換後,另外的實例可以繼續響應同一個session的請求。

以上即為Redis實現session共享高可用的一些關鍵內容。有興趣的朋友可以看下通過Memcached實現高可用,也是這個原理。順著這個思路,如果你有將Session存儲在其它地方的需求時,完全可以寫一個出來,自己動手,豐衣足食。

總結一下,我們是通過自定義的Valve來實現請求後session的攔截,同時,使用自定義的SessionManager,來滿足不同的session創建與存儲的需求。而至於是存儲在Redis/Memcached中,還是存儲在DB中,只是位置的區別。原理,是一致的。

關於PHP-Apache-Mysql高並發集群(詳細加雙倍分)

這個這樣說很難說詳細,第一可以用阿里雲的SLB,但是我沒配置這個, 具體實施不清楚,而且要保證2台或者3台伺服器的數據是一致的。理想情況下是可以用nginx做反向代理或者用lvs,不熟起來相對有些小小難度。建議不要用windows了。具體可以詳聊。

php ecshop 搭建伺服器集群

這個只需要諮詢一下伺服器廠商(比如正睿伺服器等),就諮詢一下網站做伺服器集群相關內容(以購買伺服器的方式諮詢效果最好),這種廠商對這方面應該很清楚。

原創文章,作者:XEHK,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/136969.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
XEHK的頭像XEHK
上一篇 2024-10-04 00:17
下一篇 2024-10-04 00:17

相關推薦

  • PHP和Python哪個好找工作?

    PHP和Python都是非常流行的編程語言,它們被廣泛應用於不同領域的開發中。但是,在考慮擇業方向的時候,很多人都會有一個問題:PHP和Python哪個好找工作?這篇文章將從多個方…

    編程 2025-04-29
  • 伺服器安裝Python的完整指南

    本文將為您提供伺服器安裝Python的完整指南。無論您是一位新手還是經驗豐富的開發者,您都可以通過本文輕鬆地完成Python的安裝過程。以下是本文的具體內容: 一、下載Python…

    編程 2025-04-29
  • STUN 伺服器

    STUN 伺服器是一個網路伺服器,可以協助網路設備(例如 VoIP 設備)解決 NAT 穿透、防火牆等問題,使得設備可以正常地進行數據傳輸。本文將從多個方面對 STUN 伺服器做詳…

    編程 2025-04-29
  • PHP怎麼接幣

    想要在自己的網站或應用中接受比特幣等加密貨幣的支付,就需要對該加密貨幣擁有一定的了解,並使用對應的API進行開發。本文將從多個方面詳細闡述如何使用PHP接受加密貨幣的支付。 一、環…

    編程 2025-04-29
  • 解決docker-compose 容器時間和伺服器時間不同步問題

    docker-compose是一種工具,能夠讓您使用YAML文件來定義和運行多個容器。然而,有時候容器的時間與伺服器時間不同步,導致一些不必要的錯誤和麻煩。以下是解決方法的詳細介紹…

    編程 2025-04-29
  • 使用Go-Redis獲取Redis集群內存使用率

    本文旨在介紹如何使用Go-Redis獲取Redis集群的內存使用率。 一、Go-Redis簡介 Go-Redis是一個用於連接Redis伺服器的Golang客戶端。它支持Redis…

    編程 2025-04-28
  • 使用PHP foreach遍歷有相同屬性的值

    本篇文章將介紹如何使用PHP foreach遍歷具有相同屬性的值,並給出相應的代碼示例。 一、基礎概念 在講解如何使用PHP foreach遍歷有相同屬性的值之前,我們需要先了解幾…

    編程 2025-04-28
  • 如何選擇MySQL伺服器文件許可權

    MySQL是一種流行的關係型資料庫管理系統。在安裝MySQL時,選擇正確的文件許可權是保證安全和性能的重要步驟。以下是一些指導您選擇正確許可權的建議。 一、許可權選擇 MySQL伺服器需…

    編程 2025-04-27
  • PHP獲取301跳轉後的地址

    本文將為大家介紹如何使用PHP獲取301跳轉後的地址。301重定向是什麼呢?當我們訪問一個網頁A,但是它已經被遷移到了另一個地址B,此時若伺服器端做了301重定向,那麼你的瀏覽器在…

    編程 2025-04-27
  • 如何將Python代碼部署到伺服器

    Python是一種高級編程語言,常被用於數據分析、機器學習、Web開發等不同領域的工作。但是,只有將Python代碼部署到伺服器上,才能讓其真正發揮作用。 一、選擇伺服器 要將Py…

    編程 2025-04-27

發表回復

登錄後才能評論