導航:首頁 > 編程語言 > nodejsmemorystore

nodejsmemorystore

發布時間:2023-05-29 14:36:38

① nodejs的錯誤Cannot read property 'length' of undefined,怎麼解決啊我是菜鳥

1、在使用connect-mongo包進行連接mongo資料庫時,會報Cannot read property 'Store' of undefined的錯誤

2、出現這個問題的原因是connect-mongo版本的問題,以後大家在遇到類似的問題的時候,先看看相關包目錄下的readme文件,裡面有這個包的新用法,已經這個版本和以前版本的區別。

3、我們看到connect-mongo目錄下的readme文件中有這么一段話:With express:var express = require('express'); var MongoStore = require('connect-mongo')(express); app.use(express.session({ secret: settings.cookie_secret, store: new MongoStore({db: settings.db},With connect:var connect = require('connect');var MongoStore = require('connect-mongo')(connect);

4、所以我們需要這樣修改程序:將var MongoStore = require('connect-mongo') 換成var MongoStore = require('connect-mongo')(express);且var express = require('express');這句必須在前面。這樣修改問題就解決了。

② 基於NodeJS的高性能分布式游戲日誌系統

最近我司需要做一個統一的游戲日誌系統,要求有一定的通用性,能應對公司所有的游戲業務。接下來分享一下這次日誌系統的項目經驗。

目前流行的日誌系統為ELK,由Beats、Logstash、Elasticsearch、Kibana等組件共同實現,但萬變不離其宗,一個基本的日誌系統架構類似如下:

游戲分析,與其它服務系統不同的是,游戲內的系統可能是天馬行空的,數據類型是多樣的,甚至頻繁變化的。我們要在變化中總結到不變的內容,例如系統經濟產出,玩家物品消耗,商店購買等進行分析。所以這次的游戲日誌系統要滿足以下需求:

雖然ELK在安裝配置方面不算困難,插件眾多,例如Filebeat,讀log文件,過濾格式,轉發,但誰來生產這些log文件,沒有提及。實際上,業務具有多樣性,只要有日誌文件的地方,它就可以用。例如多數會使用Nginx進行日誌收集。我們也需要考慮到日誌生產者的問題,責權分離,需要單獨一台機子進行日誌採集。

游戲是一種技術與藝術結合的產品,數據龐雜,形態各異,光日誌埋點也花不少功夫復雜,但不能因此放棄治療。好的游戲日誌,還可以幫我們還原玩家玩家畫像。游戲更新周期短,數據變化大,需要提供更實時參照報表,為非技術人員更好友的查詢界面,才能更好的服務於游戲數據分析。ELK 在這方面,基本解決了採集和儲存的問題,但實現分析方面還不能滿足我們的需求。

經過一翻思索,我們可以用現有工具,粘合多個套件,所以,我們有了以下思路:

這個框架主要使用到了Fluentd,ElasticSearch,以及NodeJS,我就稱它為 FEN 架構吧,如下圖。

上圖看出,這樣的日誌架構和第一個圖基本沒什麼不同,只是多了後面的分析與分批入庫處理,並且大量使用了NodeJS。

註:在這里不會介紹各組件的詳細的安裝配置方法,網上有太多了,怎樣使用好每一個組件才是關鍵。

先介紹我們用到的工具:

Fluentd是一個完全開源免費的log信息收集軟體,支持超過125個系統的log信息收集。Fluentd在收集源日誌方面非常方便而且高性能,通過HTTP GET就可以,這類似於Nginx的日誌記錄行為。它的優點是,日誌文件可以高度定製化,例如我們這里每5秒生成一個文件,這樣每分鍾有12個文件,每個文件體積非常小。為什麼要這樣做?下面會介紹。Fluentd還有非常多的插件,例如直接存入MongoDB,亞馬遜雲等,要是熟悉Ruby,也可以自己寫插件。

有人使用MongoDB進行日誌收集,是非常不明智的,只有幾千萬條還可以,如果半個月生產10億條日誌呢?日誌文件需要保存一個月甚至更長,那麼集群和硬碟維護就非常重要。使用便利性也很重要,例如分詞檢索,在客服回溯玩家日誌,分析游戲 BUG 的時候非常有用。下文的 ES 也是該組件的簡稱。

NodeJS不適合做 CPU 密集型任務,但在網路應用方面還不錯,並且是我們正好熟悉的。日誌系統並不對實時性要求並不高,延時半小時以內都是允許的,事實上,正常情況延時也就10來秒。下面的讀與轉發日誌的Pusher,收集日誌的logger,分析日誌並數據落袋為安的的analyser,都是由NodeJS實現的。

下面繼續介紹用 NodeJS實現的每一個部分:

上面說到,為什麼Fluentd使用分割成多個小文件的方式,因為NodeJS在大文件處理方面並不友好,並且要考慮到通過網路發送到另一台機,轉發速度比讀慢太多了,所以必須實現續傳與斷點記錄功能。想想,如果讀幾百 M 的文件,出現中斷後,需要永久記錄上次位置,下次再從此處讀起,這就增加了程序復雜度。NodeJS雖然有readline模塊,但測過發現並不如文件流那樣可控,訪模塊用於交互界面尚可。相反,如果日誌分割成多個小文件,則讀的速度非常高效,並且每5秒一個文件,哪怕有上萬條記錄,文件也大不到哪裡去,內存也不會佔用太多,在斷點續傳與出錯重試方面都能自如應對。如果游戲日誌增多,可以增加節點來緩解文件過大的壓力。

為什麼不直接讓日誌生產者直接發到Koa上?因為效率與帶寬。NodeJS的適合做網站,但比專業的HTTP伺服器要弱太多,4核心主機面對3000QPS就吃力,更多的關於NodeJS的性能問題,可以參考網路文章。在高並發量下,帶寬是個很大的問題,尤其是需要做統一服務,面對的情況是日誌機器與游戲並不在同一內網中。在10萬日活下,帶寬超過了50M,非常嚇人,帶寬可是很貴的,過高的帶寬費用在這里性價比太低了。

這里我們使用Koa作為日誌採集器。使用Koa,無論在性能還是開發效率上,都比expressJS高效。我們還用到了Redis作為緩存,而不是直接在這里做分析任務,是為了盡量提高與Pusher的對接效率,畢竟日誌的生產速度是很快的,但網路傳送是相對低效的。

註:pm2 3.2.2的集群可能出現集群內埠沖突的吊詭問題,建議用3.0.3

分析器讀取Redis的內容,這里就是單進程的隊列操作。到這一步,日誌怎麼分析,就可以很自由了。

因為我們本身有後台管理系統,所以我們很方便的把用戶畫像與其它分析點接了入去,在查詢玩家行為時,我們搜索ES,在查詢分析報表時,我們查詢MongoDB中的數據。當然我們也使用了Kibana來滿足可能的需求。

目前該日誌系統運行1個半月,由純MongoDB到結合 ES,走了不少彎路,還好現在終於穩定下來。目前在性能方面,logger 與 analyser都在同一台機,平均 CPU 為23%左右,高峰47%左右,說明還有更大的機器壓榨空間。

內存方面,在高峰期5G 以內,總體非常平穩沒多大波動,其中redis內存使用為800MB以內,但機器是16G,還有很大餘量保障。

NodeJS 的腳本中,logger的CPU佔用更小,3條進程,每條才3%,每條內存佔用不到100MB。analyser 的 CPU 與內存佔用多一點,這一點可以通過腳本內的參數調整,例如內存計數的內容清理得更快,使用pm2的話設置max_memory_restart : ƊG' 都可以提高穩定性。

以上是我在游戲日誌系統中的經驗總結。

參考文獻:

③ Memory Cache NodeJS

yarn add memory-cache

https://www.npmjs.com/package/memory-cache

④ 如何一體化一個NodeJs的MVC開發框架

本框架適合使用NodeJs進行web開發的MVC框架模式,本框架使用了express框架作為nodejs的web開發支撐,使用mysql作為資料庫開發源,下面我們就簡單的介紹如何利用本框架進行一個簡單的web應用開發。當然本框架並搏尺非官方,也並非專業設計,希望開發者共同來把本框架設計好,以便我們可以在國內實現一個NodeJs的Web開發框架。

一、項目文件夾介紹

項目文件夾主要是根據傳統的MVC設計模式,設計出來的框架。

enter image description here

二、 入口文件介紹

本框架的入口文件為index.js,該入口你可以添加多種全局靜態變數,例如你所需要的各個文件夾路徑,以及一些模塊。

舉例如下:

//========================全局變數定義===============================
global.BASE_DIR = __dirname;
global.APP = global.BASE_DIR + "/application/";
global.CON = global.APP + "/controller/";
global.CORE = global.APP + "/core/";
global.MODEL = global.APP + "/model/";
global.CONF = global.BASE_DIR + "/conf/";
global.log = global.BASE_DIR + "/log/";
global.PUBLIC = global.BASE_DIR + "/public/";
global.VIEW = global.BASE_DIR + "/view/";
/**

moles引入
*/
global.express = require(『express』);
global.sio = require(『socket.io』);
global.fs=require(『fs』);
global.path = require(『path』);
global.url = require(『url』);
global.parseCookie = require(『connect』).utils.parseCookie;
global.MemoryStore = require(『./node_moles/connect/lib/middleware/session/memory』);
global.Session = require(『./node_moles/connect/lib/middleware/session/session』);
global.sys = require(『util』);

代碼2-1:index.js

在index.js中你需要將你所有的文件夾路徑、模塊使用全局變數進行替換,該方法的優勢在於,避免用戶在編碼中引入過長的文件路徑,只需衡判要使用簡單的變數進行替換。

urlResolve = require(CORE + 「url_resolve」);
urlResolve.getActionInfo();
代碼:2-2:路由處理邏輯

本代碼包含進邏輯處理類,同時應用邏輯處理類中的getActionInfo方法,創建伺服器,並且處理url請求邏輯。

三、 路由處理邏輯

主要有六個方法,其中的getActionInfo是exports,其他咐銀改方法均為私有方法。

exports.getActionInfo = function(){
systemConfig();
app.get('/:key', function(req, res){
callUrlRequest(req, res);
});
app.post('/:key', function(req, res){
callUrlRequest(req, res);
});
listenPort();
};
function callUrlRequest(req, res){
var routerMsg = getUrlConf();
var key = req.params.key;
var session = checkSession(req, key);
if(key == "favicon.ico"){return;};
if(session == 0){
res.redirect('/index');
return;
}
console.log("[key:"+ key +"] " + "[class:" + routerMsg[key].cla + "] " + "[controller:" + routerMsg[key].fun +"]");
require(CON + routerMsg[key].con);
var controllerObj = eval("new " + routerMsg[key].cla);
controllerObj.init(req, res);
controllerObj[routerMsg[key].fun].call();
}
代碼2-3:路由處理getActionInfo
SystemConfig是配置express框架的相應數據,配置靜態文件夾以及express框架的相應配置數據。之後添加兩種url請求方式,分別是get和post方法,由於兩種方法請求資源的路由處理都是一樣的,因此使用callUrlRequest來處理。
callUrlRequest 獲取路由配置文件信息getUrlConf;
2、獲取當前訪問的key值,根據key值得到相應的配置信息,配置文件可以展示如下:
"test": {
"con" : "test",
"cla" : "test",
"fun" :"test"
},
"favicon.ico" : {
"con" : "",
"cla" : "",
"fun" : ""
},
"login" : {
"con" : "index_controller",
"cla" : "IndexController",
"fun" : "loginAct"
},
"index" : {
"con" : "index_controller",
"cla" : "IndexController",
"fun" : "loginPageAct"
},
"loginS" : {
"con" : "index_controller",
"cla" : "IndexController",
"fun" : "toMainPageAct"
}
}
代碼2-4:配置文件信息
如果當前key為test那麼我們就可以得到相應的controller、class和function。同時因為nodejs伺服器每次請求數據的時候都會加入favicon.ico,因此在代碼中我們需要將其剔除。對於checkSession就是驗證登錄信息。
3. 得到controller、class和function,首先require相應的controller,然後使用eval來new相應對象,使用controllerObj[routerMsg[key].fun].call();該方法進行調用。(本部分處理,涉及到一個javaScript的小技巧,如何對一個字元串進行new,同時調用一個對象的方法,該方法名為字元串變數)
4. 最後就是listenPort();進行監聽事件,也是伺服器開始啟動。這樣一個基本的路由處理就完成實現了。
**四、 數據層實現**
本系統數據層基類是在core文件夾下的base_model.js,該類主要包含資料庫的一般方法,主要含有資料庫鏈接、資料庫操作基本方法add、update、deleteItem、query、select等,具體實現方式,就不細講。
BaseModel為基類,其他對應於相應的表的類都繼承來自BaseModel基類
繼承方法使用JavaScript的原型繼承:
IndexController.prototype = new BaseController();
global.IndexController = IndexController;
**五、 邏輯層實現**
類同於數據層的實現方法,其繼承都是來自於基類BaseController,BaseController現只包含三個方法:init、displayHtml、displayJade。
**六、 代碼規范
** 本框架不要求開發者是如何去定義代碼規范,但本框架實現的代碼規范是如下:
變數命名:私有變數統一使用」_name」,全局變數使用大寫」VIEW」,簡單變數請使用駱駝峰」myName」
方法命名:所有方法請使用駱駝峰」getUrlRequest」
類命名:統一使用首字母大寫駱駝峰」BaseController」
文件命名:統一使用下劃線分割,類使用下劃線分割base_controller.js
總結:整體上就可以實現一個MVC開發的MyWeb框架,其中的方法以及實現都還是處於稚嫩期,希望有開發者願意加入,並且能夠團隊合作開發出我們國內優秀的NodeJs的MVC框架。

⑤ nodejs_bug修復

1、Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

<--- Last few GCs --->

[3628:0000020F92556310] 101267813 ms: Mark-sweep 2045.8 (2063.6) -> 2045.7 (2061.1) MB, 823.6 / 0.0 ms (+ 217.9 ms in 2 steps since start of marking, biggest step 217.9 ms, walltime since start of marking 1052 ms) (average mu = 0.052, current mu = 0.011)

<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x016990671ba1 <JSObject>
1: parseMessage [00000302F1DB3371] [C:\Platform\node\service\node_moles\pg\lib\connection.js:~377] [pc=0000028DA566DDB0](this=0x03d27f47c261 <Connection map = 0000012A6A060F51>,0x03e134ba35c9 <Uint8Array map =
0000012A6A065321>)
2: /* anonymous */ [0000020ACD5EAF31] [C:\Platform\node\service\node_moles\pg\lib\connection.js:~119] [pc=0000028DA56...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 00007FF78BAC094F napi_wrap+124431
2: 00007FF78BA62696 v8::base::CPU::has_sse+34502
3: 00007FF78BA63356 v8::base::CPU::has_sse+37766
4: 00007FF78C266F4E v8::Isolate::+94
5: 00007FF78C24EF91 v8::SharedArrayBuffer::Externalize+833
6: 00007FF78C11C85C v8::internal::Heap::+1436
7: 00007FF78C127C00 v8::internal::Heap::+1312
8: 00007FF78C124734 v8::internal::Heap::PageFlagsAreConsistent+3204
9: 00007FF78C119FC3 v8::internal::Heap::CollectGarbage+1283
10: 00007FF78C118794 v8::internal::Heap::AddRetainedMap+2356
11: 00007FF78C140623 v8::internal::Factory::NewRawOneByteString+83
12: 00007FF78C1434D2 v8::internal::Factory::NewStringFromUtf8+130
13: 00007FF78C26386A v8::String::NewFromUtf8+298
14: 00007FF78B9D76EF node::tracing::TraceEventHelper::SetAgent+40751
15: 00007FF78BA79BFD v8::internal::Malloced::operator delete+1661
16: 00007FF78C61341C v8::internal::SetupIsolateDelegate::SetupHeap+4562817: 0000028DA566DDB0

2、<--- JS stacktrace --->
Cannot get stack trace in GC.
FATAL ERROR: MarkCompactCollector: semi-space , fallback in old gen Allocation failed - JavaScript heap out of memory

這個問題是node內存泄漏造成的。因為node是單線程的,所有的訪問走的一個線程,如果執行完一個,佔用內存增加,但是沒有釋放的話,就造成內存泄漏,內存泄漏其實就是存儲泄漏,而造成的原因就是內存分配超過了v8內存的限制數量,而且進程所佔用的內存,並沒有慢慢釋放回來,

解決辦法:node --max-old-space-size=6096 analysis.js

⑥ Nodejs的WebSocket模塊怎麼設置連接超時時間

在建立socket連接時可以很容易設置socket通信的發送和接收超時時間,但是在建立socket通信時,如果是Win98系統,則如果連接失敗,則程序會一直等待在哪裡,Windows2000默認超時時間是30秒,當然,這個超時時間不算長,但是加入我們要循環掃描一系列埠並且建立連接的話,總的等待時間就會讓人忍受不了,下面就以delphi為例進行說明,如何在建立socket的時候設置其超時時間:
//連接,發送和接收時間都設為2秒
SctTimeOut := 2000;
//設置接收數據通信超時
setsockopt(hSock,SOL_SOCKET,SO_RCVTIMEO,@SctTimeOut,SizeOf(Integer));
//設置發送數據通信超時
setsockopt(hSock,SOL_SOCKET,SO_SNDTIMEO,@SctTimeOut,SizeOf(Integer));
//首先,設置通訊為非阻塞模式
dwArg := 1;
RecvLen := ioctlsocket(hSock,FIONBIO,dwArg);
//其次,連接伺服器
ZeroMemory(@addr, sizeof(addr));
addr.sin_family := AF_INET;
addr.sin_addr.S_addr := inet_addr(pchar(SvrIP));
addr.sin_port := htons(Strtoint(SvrPort));
RecvLen := 0;
RecvLen := connect(hSock, addr, sizeof(addr));
//再次,設置連接超時時間為2秒
tmOut.tv_sec := 2;
tmOut.tv_usec := 0;
FD_ZERO(recvSet);
FD_SET(hSock, recvSet);

RecvLen := select(0, @recvSet, @recvSet, nil, @tmOut);
//連接失敗,報錯誤信息
if (RecvLen = 0) or (RecvLen = SOCKET_ERROR) then
begin
ErrMsg := '連接伺服器失敗!';
exit;
end;
//最後,設置通訊為阻塞模式
dwArg := 0;
RecvLen := ioctlsocket(hSock,FIONBIO,dwArg);
//end modify

⑦ nodejs怎麼占內存那麼多

node基於v8構建,所以在node中使用的js對象基本上都是通過v8自己的方式來進行分配和管理的。
在v8中,所有的js對象都是通過堆來進行分配的。

process.memoryUsage();
{
rss:24473600,
heapTotal: 7331840,
heapUsed: 5736952,
external: 8727
}

v8內存分代
v8中,主要將內存分為新生代和老生代。新生代中為存活時間較短的對象,老生代中為存活時間較長的對象。

新生代垃圾回收:
新生代中的對象主要通過Scavenge演算法進行垃圾回收。將新生代中的內存空間一分為二,處於使用狀態的為From空間,處於閑置狀態的為To空間。在進行垃圾回收時,檢查From空間的存活對象並復制到To空間,非存活對象佔用空間釋放。之後From和To空間角色對調。

對象晉升:
如果一個對象經歷過一次新生代垃圾回收,或者To空間的內存佔比超過25%,則此對象從新生代中移動到老生代中,此過程稱為晉升。

老生代垃圾回收:
主要採用Mark-Sweep(標記清除)和Mark-Compact(標記整理)兩種方式進行垃圾回收。
標記清除在標記階段遍歷堆中的所有對象,並標記活著的對象。隨後的清除中只清除沒有被標記的對象。會產生內存碎片。為解決這個問題,標記整理被提了出來,在對象被標記為死亡後,在整理的過程中,將活著的對象往一端移動,移動完成後直接清理掉邊界外的內存。v8中混合使用這兩種方法。一般在空間不足以對從新生代晉升過來的對象進行分配時,才使用標記整理。

高效使用內存:
在js中無法立即回收的內存有閉包和全局變數引用這兩種情況。此情況會導致新生代中的對象數量增多。


⑧ webpack打包報javaScript heap out of memory,怎麼解決

哎,我終於自己搞定了。其實,現在發現我已開始的解決問題的思路沒有錯,就是往node命令行裡面添加 "--max_old_space_size"。錯就錯在,加的地方加錯了(可能是針對我這種環境不起作用?)。一開始我是參考了segmentfault上面一個同樣的weback打包導致nodejs內存溢出的一個問題所提供的方案來做的,就是在全局的webpack.cmd(路徑是:C:.cmd)裡面添加,

閱讀全文

與nodejsmemorystore相關的資料

熱點內容
彩視製作教程 瀏覽:766
聖墟在哪個App看免費 瀏覽:395
網路哪些不能玩 瀏覽:868
probe315使用教程 瀏覽:646
數字電位器程序 瀏覽:198
c代碼整理 瀏覽:104
網路營銷具有什麼優勢 瀏覽:378
右下角網路連接不顯示寬頻連接 瀏覽:940
ps修改tif文件 瀏覽:580
預防醫學如何轉行做大數據 瀏覽:234
pdf文件變藍 瀏覽:309
怎麼在pdf文件上面用k寶簽名 瀏覽:213
如何知道表格里數據後面有空格 瀏覽:720
gee引擎更新系統找不到指定文件 瀏覽:802
貝殼網的數據刪除了如何找回 瀏覽:509
華為榮耀6x怎麼切換網路 瀏覽:418
手機里的pdf文件在哪放 瀏覽:889
java版貪吃蛇畢業論文 瀏覽:989
微信公共號郵箱 瀏覽:415
圖片寬度代碼 瀏覽:460

友情鏈接