最近在開發(fā)MySQL代理中間件過程中, 遇到這樣一個問題: 當前后端連接不是一一對應的關系時, 對前端連接設置SESSION級別的變量時, 如何能使前端后變量的值保持一致?
創(chuàng)新互聯(lián)專注于企業(yè)成都全網營銷推廣、網站重做改版、撫順網站定制設計、自適應品牌網站建設、H5頁面制作、商城網站建設、集團公司官網建設、外貿網站制作、高端網站制作、響應式網頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為撫順等各大城市提供網站開發(fā)制作服務。
一個直觀的實現方式是, 攔截SET語句, 判斷scope是SESSION時, 將變量的值保存在前端連接中. 當執(zhí)行其他查詢語句時, 在獲取后端連接后, 先將前端連接中保存的變量逐一發(fā)送到后端連接, 然后執(zhí)行查詢語句, 釋放后端連接時再將變量的值恢復.
這種實現方式存在幾個顯著的問題.
1 存在一定的性能損耗, 至少增加了1次與后端MySQL的交互. 但是, 這也是后端連接池方案都會遇到的問題, 前后端連接綁定不存在這種問題, 但是也就失去了連接池帶來的好處.
2 需要判斷參數值是否合法, 實現起來非常繁瑣. 例如, 如果考慮支持字符集設置, 就要枚舉出MySQL支持的所有字符集及字符序類型, 解析 SET NAMES 'utf8' COLLATE 'utf8_general_ci' 時, 對字符集和字符序進行合法性判斷. 對于某些參數, 例如sql_mode, 還需要考慮MySQL版本之前的差異.
在這種實現方式下, 有幾個優(yōu)化點可以參考.
1 批量執(zhí)行SET語句. MySQL語法層面支持 SET SESSION var1 = val1, SESSION var2 = val2; , 因此不論前端連接接收到的SET語句是單條的還是批量的, 在將這些kv值發(fā)往后端時, 可以整合成一條SQL, 從而減少與MySQL的交互次數, 提高執(zhí)行效率.
2 后端連接按需重置. 當歸還后端連接時, 不再重置連接, 而是在下一次獲取連接時, 先判斷連接中的變量值與前端連接是否全部相同, 如果全部相同, 則不需要重置, 可以直接使用, 否則, 將那些值不相同的變量設置到后端連接.
3 使用 COM_RESET_CONNECTION 命令重置連接. COM_RESET_CONNECTION命令可以將連接恢復到初始狀態(tài), 具體內容可參考文檔: . 但是, 如果連接創(chuàng)建時的狀態(tài)不是連接的默認狀態(tài), 就不能使用這種方式重置連接. 例如, 在啟動mysql client時指定的字符集不是DEFAULT, 那么執(zhí)行該命令后會錯誤地把連接的字符集設置成DEFAULT.
最后, 如果你有更好的解決方案, 歡迎討論交流.
Node.JS 服務器可以在 后端 連接mysql,這時的情況和php是一樣的。
我從未見過前端JS直接連接mysql的,原因是:
(1)瀏覽器內置的javascript 引擎一般只支持websocket,即基于http連接的套接字高層協(xié)議,而不是真正的socket,因此除非服務器端也開啟websocket服務并拆開套接字轉發(fā)到mysql,否則無法代理連接
(2)我見過的絕大多數mysql 服務器都工作在服務器環(huán)境下的一個虛擬子網,換句話說,直接的遠程3306端口是拒絕連接的,這樣可以隔絕端口直接攻擊
如果前段js直接可以連接后端服務器mysql的端口,那么就不叫B/S結構了,而是C/S結構(比如傳統(tǒng)的windows桌面程序),安全上有很多問題,所以大多數瀏覽器也不支持這個操作。
首先要明白一個概念 js是客戶端加載的不可能讓客戶端直接連數據庫,
如果連了就不安全啊,
所以需要服務端連接數據庫,服務端js連數據庫我只知道node.js,你可以看看
套路就是客戶端請求服務端,服務端連接數據庫獲取值再返回到客戶端