Node + Express/Koa2 + PM2 + MySQL/Redis
- Nodejs๏ผไธไธชjs่ฟ่ก็ฏๅข
- ่ฟ่กๅจๆๅก็ซฏ๏ผไฝไธบweb server
- ่ฟ่กๅจๆฌๅฐ๏ผไฝไธบๆๅ ๏ผๆๅปบๅทฅๅ ท
- API
- ๆฐๆฎๅญๅจ
- ็ปๅฝ
- ๆฅๅฟ
- ๅฎๅ จ
- HTTP
- Stream
- Session
- MySQL/Redis
- Nginx
- PM2
- Nodeไป็ป --- Nodeๅฎ่ฃ Nodeๅjsๅบๅซ
- ๆๅก็ซฏ็น็น--- ๆๅก็ซฏ็น็น ๆๅก็ซฏๅๅ็ซฏ็ๅบๅซ
- ๆกไพๅๆๅ่ฎพ่ฎก--- ๅๅฎข้กน็ฎ็้ๆฑๅๆๅๆๆฏๆนๆก่ฎพ่ฎก
- ไฝฟ็จๅ็ไปฃ็ ๅผๅๆกไพ้กน็ฎ
- ๅฎ็ฐAPIๅๆฐๆฎๅญๅจ๏ผไฝฟ็จMySQLๆฐๆฎๅบ
- ไป0ๅฎ็ฐ็ปๅฝ๏ผๅนถไฝฟ็จredisๅญๅจ็ปๅฝไฟกๆฏ
- ๅฎๅ จ๏ผๆฅๅฟ่ฎฐๅฝๅๆฅๅฟๅๆ
- ไฝฟ็จๆกๆถๅผๅๆกไพ้กน็ฎ
- ๅๅซไฝฟ็จexpress ๅKoa2
- ไธญ้ดไปถๆบๅถ
- ๅธธ็จๆไปถ
- ไธญ้ดไปถๅ็
- ็บฟไธ็ฏๅข
- PM2ไป็ปๅ้ ็ฝฎ
- PM2ๅค่ฟ็จๆจกๅ
- ๅ ณไบๆๅกๅจ่ฟ็ปด
- APIๅๆฐๆฎๅญๅจ
- ็ปๅฝๅRedis
- ๅฎๅ จๅๆฅๅฟ
- Express ๅ Koa2
- ไธญ้ดไปถๅๆไปถ
- ไธญ้ดไปถๅ็
- PM2ไป็ปๅ้ ็ฝฎ
- PM2ๅค่ฟ็จๆจกๅ
- ๆๅกๅจ่ฟ็ปด
1.ๆฎ้ๆนๅผ nodejs.cn ๅฎ็ฝ
2.NVM node็ๆฌ็ฎก็ๅทฅๅ
ท
Mac brew install nvm
Window githubๆnvm-windows
nvm list # ๆฅ็ๅฝๅๆๆ็node็ๆฌ
nvm install v10.15.0 # ๅฎ่ฃ
ๅถๅฎ็ๆฌ
nvm use --delete-prefix 10.13.0 # ๅๆขๅฐๆๅฎ็ๆฌ
-
ESMAScript -- ่ฏญๆณ่ง่
ๅฎไนไบ่ฏญๆณ ๏ผๅjs็nodeๅฟ ้กป้ตๅฎ ๅ้ๅฎไน๏ผๅพช็ฏ๏ผๅคๆญ๏ผๅฝๆฐ ๅๅๅๅๅ้พใไฝ็จๅๅ้ญๅ ใๅผๆญฅ ไธ่ฝๆไฝDOM๏ผไธ่ฝ็ๅฌclickๆถ้ด๏ผไธ่ฝๅ้ajax่ฏทๆฑ ไธ่ฝๅค็http่ฏทๆฑ๏ผไธ่ฝๆไฝๆไปถ ๅชๆESMAScript๏ผๆ ๆณๅ้กน็ฎ
-
Javascript
ไฝฟ็จESMAScript่ฏญๆณ่ง่๏ผๅคๅ Web API๏ผ็ผบไธไธๅฏ๏ผESMAScript + Web API๏ผ DOMๆไฝ๏ผBOM๏ผไบไปถ๏ผAjax... ไธค่ ็ปๅ๏ผๅณๅฏๅฎๆๆต่งๅจ็ซฏ็ๆไฝ
-
NodeJs
ไฝฟ็จESMAScript่ฏญๆณ่ง่๏ผๅคๅ Node API๏ผ็ผบไธไธๅฏ๏ผESMAScript + Node API๏ผ ๅค็http๏ผๅค็ๆไปถ็ญAPI ไธค่ ็ปๅ๏ผๅณๅฏๅฎๆserver็ซฏ็ๆไฝ
-
่กฅๅ :Commonjs & Node debugger
-
Commonjs
# ๅฏผๅบ
module.exports = ๅ้
module.exports = ๅฏน่ฑก
# ๅผๅ
ฅ1
const {a,b} = require('./a); //่งฃๆๅผๅ
ฅ
# ๅผๅ
ฅ2
const opt = require('./a);
const a = opt.a
const b = opt.b
- Node bugger
ๅฉ็จvscode่ชๅธฆ็debuggerๅ่ฝ๏ผไผๆ นๆฎ
package.json้็mainๅญๆฎตๅปๆพๅ ฅๅฃ
- server ็ซฏๅฏ่ฝไผ้ญๅๅ็งๆถๆๆปๅปๅ่ฏฏๆไฝ
- ๅไธชๅฎขๆท็ซฏๅฏไปฅๆๅคๆๆ๏ผไฝๆฏๆๅก็ซฏไธ่ฝ
- ๅฏไปฅไฝฟ็จPM2ๅ่ฟ็จๅฎๆค
- ๆฅๅฟ่ฎฐๅฝ
- ๅฎๅ จ
- ้็พคๅๆๅกๆๅ
- ๅผๅๅๅฎข็ณป็ป๏ผๅ ทๆๅๅฎข็ๅบๆฌๅ่ฝ
- ไนๅผๅserver็ซฏ๏ผไธๅ ณๅฟๅ็ซฏ
- ้ฆ้กตใไฝ่ ไธป้กตใๅๅฎข่ฏฆๆ ้กต
- ็ป้้กต
- ็ฎก็ไธญๅฟใๆฐๅปบ้กตใ็ผ่พ้กต
- ๅๅฎข
| id | title | content | createtime | author |
|---|---|---|---|---|
| 1 | ๆ ้ข1 | ๅๅฎข1 | ๅๅปบๆถ้ดxxx-xxx-xxx | xxx |
| 2 | ๆ ้ข2 | ๅๅฎข2 | ๅๅปบๆถ้ดxxx-xxx-xxx2 | xxx2 |
- ็จๆท
| id | username | password | realname |
|---|---|---|---|
| 1 | zhangsan | 123 | ๅผ ไธ |
| 2 | lisi | 456 | ๆๅ |
| ๆ่ฟฐ | ๆฅๅฃ | ๆนๆณ | urlๅๆฐ | ๅคๆณจ |
|---|---|---|---|---|
| ่ทๅๅๅฎขๅ่กจ | /api/blog/list | get | authorไฝ่ ๏ผkeywordๆ็ดขๅ ณ้ฎๅญ | ๅๆฐไธบ็ฉบ๏ผๅไธ่ฟ่กๆฅ่ฏข่ฟๆปค |
| ่ทๅไธ็ฏๅๅฎข็ๅ ๅฎน | /api/blog/detail | get | id | |
| ๆฐๅขไธ็ฏๅๅฎข | /api/blog/new | post | postไธญๆๆฐๅข็ไฟกๆฏ | |
| ๆดๆฐไธ็ฏๅๅฎข | /api/blog/update | post | id | postDataไธญๆๆดๆฐ็ๅ ๅฎน |
| ๅ ้คไธ็ฏๅๅฎข | /api/blog/del | post | id | |
| ็ปๅฝ | /api/user/login | post | postDataไธญๆ็จๆทๅๅๅฏ็ |
- ไธ็ๆ็ปไธ็่งฃๅณๆนๆก๏ผไธ่ฌไธ็จๅ้ๆฐ่ฎพ่ฎก
- ๅๅ -- > ip+port
- get่ฏทๆฑ๏ผๅณๅฎขๆท็ซฏ่ฆๅserver็ซฏ่ทๅๆฐๆฎ๏ผๅฆๆฅ่ฏขๅๅฎขๅ่กจ
- ้่ฟquerystringไผ ้ๆฐๆฎ๏ผๅฆ a.html?a=100&b=200
const http = require('http');
const querystring = require('querystring');
const server = http.createServer((req,res)=>{
console.log(req.method)
const url = req.url;
console.log(url);
const queryStr = url.split('?')[1]; //ๆ นๆฎ้ฎๅทๆๅๅๆฐ
req.query = querystring.parse(queryStr);
res.end(JSON.stringify(req.query));
});
server.listen(8000);
- ๅฎขๆท็ซฏๅๆๅก็ซฏไผ ้ๆฐๆฎ๏ผๅฆๆฐๅปบๅๅฎข
- ้่ฟpost dataไผ ้ๆฐๆฎ
- ๆต่งๅจๆ ๆณ็ดๆฅๆจกๆ๏ผ้่ฆๆๅjs๏ผๆ่
ไฝฟ็จpostman
const http = require('http');
const log = console.log;
const server = http.createServer((req,res)=>{
if(req.method ==="POST"){
// req ๆฐๆฎๆ ผๅผ
log('req content-type',req.headers['content-type']);
// ๆฅๆถๆฐๆฎ
let postData = '';
req.on('data',chunk=>{
postData += chunk.toString();
});
req.on('end',()=>{
log('postData',postData);
res.end('hello post')
})
}
});
server.listen(8001);
1.Chromeไธๅฎ่ฃ postmanๆไปถ 2.ๅฐๅๆ ่พๅ ฅ่ฎฟ้ฎๅฐๅ http://localhost:8001๏ผไฟฎๆน่ฏทๆฑไธบPOST 3.็นๅปไธๆน โBodyโ ---> raw ๅณไพง้ๆฉ JSON ---> ไธๆน็ฉบ็ฝๅบ ่พๅ ฅ่ฏทๆฑๅๆฐjson
่งฃๆreq.url ้็/username /password็ญ
const http = require('http');
const querystring = require('querystring');##
const log = console.log;
const server = http.createServer((req,res)=>{
const method = req.method;
const url = req.url;
const query = querystring.parse(url.split('?')[1]);
const path = url.split('?')[0]
res.setHeader('Content-type','application/json');
const resData = {
method,
url,
query,
path
}
if(method==='GET'){
res.end(JSON.stringify(resData))
}
if(method==='POST'){
let postData = '';
req.on('data',chunk => {
postData += chunk
});
req.on('end',()=>{
log('postData',postData);
resData.postData = postData
res.end(JSON.stringify(resData));
})
}
});
server.listen(8002);
- ไป0ๅผๅงๆญๅปบ๏ผไธไฝฟ็จไปปไฝๆกๆถ
- ไฝฟ็จnodemon็ๆตๆไปถๅๅ๏ผ่ชๅจ้ๅฏnode
- ไฝฟ็จcross-env ่ฎพ็ฝฎ็ฏๅขๅ้๏ผๅ ผๅฎนmac/linux/windows
- ๅๅงๅ่ทฏ็ฑ๏ผๆ นๆฎไนๅๆๆฏๆนๆก็่ฎพ่ฎก๏ผๅๅบ่ทฏ็ฑ
- ่ฟๅๅๆฐๆฎ๏ผๅฐ่ทฏ็ฑๅๆฐๆฎๅ็ฆป๏ผไปฅ็ฌฆๅ่ฎพ่ฎกๅๅ
โโโ app.js -- ไธป่ฆๆๅก
โโโ bin
โ โโโ www.js --- ๅๅปบๆๅก
โโโ controllers --- ๆพๅๆฐๆฎ
โ โโโ index.js
โโโ models --- ่ฟๅๆญฃ็กฎ/้่ฏฏ ็ปไธๆฐๆฎๆ ผๅผ Model
โ โโโ index.js
โโโ package-lock.json
โโโ package.json
โโโ routers -- ่ทฏ็ฑๆไปถ๏ผ่งฃๆ่ฏทๆฑ
โโโ blog.js
โโโ user.js
# blog.js
const handleBlogRouter = (req,res) =>{
const method = req.method;
const path = req.url.split('?')[0];
//่ทๅๅๅฎขๅ่กจ /api/blog/list
if( method==="GET" && path === "/api/blog/list"){
return {
msg:'/api/blog/list'
}
}
//่ทๅไธ็ฏๅๅฎข็ๅ
ๅฎน /api/blog/detail
if( method==="GET" && path === "/api/blog/detail"){
return {
msg:'/api/blog/detail'
}
}
//ๆฐๅขไธ็ฏๅๅฎข /api/blog/new
if( method==="POST" && path === "/api/blog/new"){
return {
msg:'/api/blog/new'
}
}
//ๆดๆฐไธ็ฏๅๅฎข /api/blog/update
if( method==="POST" && path === "/api/blog/update"){
return {
msg:'/api/blog/update'
}
}
//ๅ ้คไธ็ฏๅๅฎข /api/blog/del
if( method==="POST" && path === "/api/blog/update"){
return {
msg:'/api/blog/update'
}
}
}
module.exports = handleBlogRouter;
# user.js
const handleUserRouter = (req,res) =>{
const method = req.method;
const path = req.url.split('?')[0];
//่ทๅๅๅฎขๅ่กจ /api/user/login
if( method==="POST" && path === "/api/user/login"){
return {
"msg":"/api/user/login"
}
}
}
module.exports = handleUserRouter;
# app.js
const handleBlogRouter= require('./routers/blog');
const handleUserRouter = require('./routers/user');
const serverHandle = (req,res) => {
//่ฎพ็ฝฎ่ฟๅ็JSON
res.setHeader('Content-type','application/json');
const blogData = handleBlogRouter(req,res);
if(blogData){
res.end(JSON.stringify(blogData));
}
const userData = handleUserRouter(req,res);
if(userData){
res.end(JSON.stringify(userData));
}
}
module.exports = serverHandle;
# app.js
const queryString = require('querystring');
const handleBlogRouter= require('./routers/blog');
const handleUserRouter = require('./routers/user');
//่งฃๆpost data๏ผ่ฟๅpromiseๅฏน่ฑก
const getPostData = (req) => {
const promise = new Promise((resolve,reject) => {
if(req.method === "POST" && req.headers['content-type'] === 'application/json'){
let postData = "";
req.on('data',chunk => postData += chunk.toString());
req.on("end",()=>{
if(postData){
resolve(JSON.parse(postData));
}else{
resolve({});
return;
}
})
}else{
resolve({});
return;
}
});
return promise;
}
const serverHandle = (req,res) => {
//่ฎพ็ฝฎ่ฟๅ็JSON
res.setHeader('Content-type','application/json');
//่ทๅpath
const url = req.url;
req.path = url.split('?')[0];
req.query = queryString.parse(url.split('?')[1])
//่งฃๆpostๆฐๆฎ
getPostData(req).then(postData => {
req.body = postData;
//ๅค็ๅๅฎข็่ทฏ็ฑ
const blogData = handleBlogRouter(req,res);
if(blogData){
res.end(JSON.stringify(blogData));
}
//ๅค็็จๆท็ปๅฝ็่ทฏ็ฑ
const userData = handleUserRouter(req,res);
if(userData){
res.end(JSON.stringify(userData));
}
})
}
module.exports = serverHandle;
# ๅปบ็ซ่ฟๅ็ๆฐๆฎๆ ผๅผModel models/index.js
class BaseModel {
constructor(data,message){
if(typeof data === "string"){
this.message = data;
data = null;
message = null
}
if(data){
this.data = data;
}
if(message){
this.message = message;
}
}
}
class SuccessModel extends BaseModel {
constructor(data,message){
super(data,message);
this.errno = 0;
}
}
class ErrorModel extends BaseModel {
constructor(data,message){
super(data,message);
this.errno = -1;
}
}
module.exports = {
SuccessModel,
ErrorModel
}
# ่งฃๆ ๅๅฎข่ทฏ็ฑ routers/blog.js
const {
getList,
getDetail,
newBlog,
updateBlog,
delBlog
} = require('../controllers/blog')
const { SuccessModel,ErrorModel } = require('../models')
const handleBlogRouter = (req,res) =>{
const method = req.method;
const path = req.path;
const query = req.query;
const id = query && query.id;
//่ทๅๅๅฎขๅ่กจ /api/blog/list
if( method==="GET" && path === "/api/blog/list"){
const { author , keyword } = query;
if(author && keyword){
const resData = getList(author,keyword);
return new SuccessModel(resData);
}else {
return new ErrorModel('่ทๅๅๅฎขๅ่กจๅคฑ่ดฅ๏ผ่ฏทไผ ๆญฃ็กฎ็ๅๆฐ author & keyword');
}
}
//่ทๅไธ็ฏๅๅฎข็ๅ
ๅฎน /api/blog/detail
if( method==="GET" && path === "/api/blog/detail"){
if(id){
const resData = getDetail(id);
return new SuccessModel(resData);
}else{
return new ErrorModel('่ทๅๅๅฎขๅ
ๅฎนๅคฑ่ดฅ๏ผ่ฏทไผ ๆญฃ็กฎ็ๅๆฐid');
}
}
//ๆฐๅขไธ็ฏๅๅฎข /api/blog/new
if( method==="POST" && path === "/api/blog/new"){
const resData = newBlog(req.body);
return new SuccessModel(resData);
}
//ๆดๆฐไธ็ฏๅๅฎข /api/blog/update
if( method==="POST" && path === "/api/blog/update"){
const resData = updateBlog(id,req.body);
if(resData){
return new SuccessModel('ๆดๆฐๅๅฎขๆๅ');
}else {
return new ErrorModel('ๆดๆฐๅๅฎขๅคฑ่ดฅ')
}
}
//ๅ ้คไธ็ฏๅๅฎข /api/blog/del
if( method==="POST" && path === "/api/blog/del"){
if(id){
const resData = delBlog(id);
if(resData){
return new SuccessModel('ๅ ้คๅๅฎขๆๅ');
}
}
}
}
module.exports = handleBlogRouter;
# ่งฃๆ็จๆท็ปๅฝ่ทฏ็ฑ routers/user.js
const { loginCheck } = require('../controllers/user');
const { SuccessModel,ErrorModel } = require('../models')
const handleUserRouter = (req,res) =>{
const method = req.method;
const path = req.path;
//่ทๅๅๅฎขๅ่กจ /api/user/login
if( method==="POST" && path === "/api/user/login"){
const { username,password } = req.body;
const result = loginCheck(username,password);
if(result){
return new SuccessModel('็ป้ๆๅ!');
}
return new ErrorModel('็ปๅฝๅคฑ่ดฅ!');
}
}
module.exports = handleUserRouter;
# ๅค็ๆฐๆฎ controllers/blog.js
const getList = (author,keyword) => {
console.log(author,keyword)
return [
{
id:1,
title:'ๅๆA',
content:"ๅ
ๅฎนA",
author:"zhangsan"
},
{
id:2,
title:'ๅๆB',
content:"ๅ
ๅฎนB",
author:"lisi"
}
]
}
const getDetail = (id) => {
return {
id:1,
title:'ๅๆA',
content:"ๅ
ๅฎนA",
author:"zhangsan"
}
}
const newBlog = (blogData = {}) => {
return {
id:3
}
}
const updateBlog = (id,blogData = {}) => {
// id ่ฆๆดๆฐ็ๅๅฎขid
// blogData ๅๅฎขๅฏน่ฑก ๅ
ๅซtitle contentๅฏน่ฑก
console.log('update blog',id,blogData);
return true;
}
const delBlog = (id) => {
//id ่ฆๅ ้ค็ๅๅฎขid
return true;
}
module.exports = {
getList,
getDetail,
newBlog,
updateBlog,
delBlog
}
# ๅค็ๆฐๆฎ controllers/user.js
const loginCheck = (username,password) => {
if(username === 'zhangsan' && password === '123'){
return true;
}
return false;
}
module.exports = {
loginCheck
}
-
web server ไธญๆๆต่ก็ๅ ณ็ณปๅๆฐๆฎๅบ
-
่ฝป้็บง๏ผๆๅญฆๆ็จ
-
ๅฎ่ฃ mysql mysql ๆง่กๅฎ่ฃ --->่ฎฐไฝroot็จๆทๅ็ๅฏ็
-
ๅฎ่ฃ mysqlๅฏ่งๅๅทฅๅ ท workbench
- ๅฆไฝๅปบๅบ๏ผๅปบ่กจ
- ๅปบ่กจๆถๅธธ็จ็ๆฐๆฎ็ฑปๅ(int,bight,varchar,longtext)
- sql ่ฏญๅฅๅฎ็ฐๅขๅ ๆนๆฅ
- ๅปบๅบ --> ๅๅปบmyblogๆฐๆฎๅบ --> ๆง่กshow databasesๆฅ่ฏข
- ๅปบ่กจ
ๅๅปบblogsๅๅฎข่กจ
| id | title | content | createtime | author |
|---|---|---|---|---|
| 1 | ๆ ้ข1 | ๅๅฎข1 | ๅๅปบๆถ้ดxxx-xxx-xxx | xxx |
| 2 | ๆ ้ข2 | ๅๅฎข2 | ๅๅปบๆถ้ดxxx-xxx-xxx2 | xxx2 |
-------------------------blogsๅๅฎข่กจ็ปๆ่ฎพ่ฎก
| column | datatype | pkไธป้ฎ | nnไธไธบ็ฉบ | AI่ชๅจๅขๅ | Deafult |
|---|---|---|---|---|---|
| id | int(ๆดๆฐ็ฑปๅ) | Y(ไธ้ๅค) | Y | Y (่ชๅข) | |
| title | varchar(50)(ๅญ็ฌฆไธฒ) | Y | |||
| content | longtext(20) | Y | |||
| createtime | bigint(20)(้ฟๆดๆฐ) | Y | 0 | ||
| author | varchar(50) | Y |
ๅๅปบusers่กจ
| id | username | password | realname |
|---|---|---|---|
| 1 | zhangsan | 123 | ๅผ ไธ |
| 2 | lisi | 456 | ๆๅ |
------------------------users็จๆท่กจ็ปๆ่ฎพ่ฎก
| column | datatype | pkไธป้ฎ | nnไธไธบ็ฉบ | AI่ชๅจๅขๅ |
|---|---|---|---|---|
| id | int(ๆดๆฐ็ฑปๅ) | Y(ไธ้ๅค) | Y | Y (่ชๅข) |
| username | varchar(20)(ๅญ็ฌฆไธฒ) | Y | ||
| password | varchar(20) | Y | ||
| realname | varchar(10) | Y |
3.ๆไฝ่กจ
# ไฝฟ็จmyblogๅบ
use myblog;
# ๆพ็คบๆๆ่กจ
show tables;
# ๆณจ้
-- show tables;
# ๅข
insert into users (username,`password`,realname) values ('zhangsan','123','ๅผ ไธ') # ๅusers่กจๆๅ
ฅusername,`password`ๅ
ณ้ฎ่ฏๅ ๅๅผๅท,realname
# ๆฅ
select * from users; # ๆฅ่ฏขusers่กจ็ๆๆๅ
ๅฎน
select id,username from users; # ๆฅ่ฏขusers่กจ็id,username
## ๆกไปถๆฅ่ฏข ๅๆถๆปก่ถณ
select * from users where username='zhangsan' and `password`='123'
## ๆกไปถๆฅ่ฏข ๅนถ้ๆฅ่ฏข ๆปก่ถณๅ
ถไธ็ๅฐฑๆพ็คบ
select * from users where username='zhangsan' or `password`='123'
## ๆจก็ณๆฅ่ฏข
select * from users where username like '%zhang%';
## ๆๅบๆฅ่ฏข(ๆญฃๅบ)๏ผๆจก็ณๆฅ่ฏขๆ1็็ปๆๆ็
งidๆๅบ
select * from users where `password` like '%1%' order by id ;
## ๆๅบๆฅ่ฏข(ๅๅบ)๏ผๆจก็ณๆฅ่ฏขๆ1็็ปๆๆ็
งidๆๅบ
select * from users where `password` like '%1%' order by id desc;
# ๆดๆฐ
update users set relname='ๆๅ2' where username='lisi'
## ๅฆๆ่งฆๅMySQLๅฎๅ
จๆบๅถ๏ผๅฏไปฅๅ
ณ้ญ,ๅๆง่กๆดๆฐ่ฏญๅฅ
SET SQL_SAFE_UPDATES=0;
# ๅ ้ค(ไธๅฎๅธฆwhereๆกไปถ)
delete from users where username="lisi";
## ้่ฟๅญๆฎตๆฅ่กจ็คบๅ ้ค๏ผ่ไธๆฏ็ๅฎdeleteๅ ้ค
select * from users where state='1';
-- select * from users where state<>'0';(ๅฆไธ็งๅๆณ <>0 ่กจ็คบไธ็ญไบ0)
update users set state='0' where username='lisi' # ่ฎพ็ฝฎstate=0่กจ็คบๅ ้ค(่ฝฏๅ ้ค)
# ๆฅ็mysql็ๆฌๅท
select version();
npm i mysql
const mysql = require('mysql');
//ๅๅปบๆฐๆฎๅบๅฏน่ฑก
const connection = mysql.createConnection({
host:'localhost',
port:'3306',
user:'xxx',
password:'xxx',
database:'myblog'
});
//ๅผๅง้พๆฅ
connection.connect();
//ๆง่กsql่ฏญๅฅ
connection.query(sql่ฏญๅฅ,(err,results)=>{
if (err) throw err;
console.log(results)
})
//ๅ
ณ้ญ
connection.end()
## ้ๅฐ็้ฎ้ข -- ๅฎ่ฃ
ๅฎๆ ๆณ่ฟๆฅmysql๏ผ้่ฏฏไฟกๆฏ
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
## ่งฃๅณๆนๆณ
mysql -u root -p #็ปๅฝmysql
Enter password: ่พๅ
ฅไฝ ๅฝๅ็mysqlๅฏ็
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password';
mysql> FLUSH PRIVILEGES;
mysql> quit
้ๆฐ่ฟๆฅnode--node mysql.js
[ RowDataPacket { id: 1, username: 'zhangsan', password: '123', realname: 'ๅผ ไธ' },
RowDataPacket { id: 2, username: 'lisi', password: '456', realname: 'ๆๅ2' } ]
# ๅๅปบdb/conf.js ๅฉ็จprocess.env.NODE_ENVๆฅๅบๅ็บฟไธๅๆฌๅฐ็ๆฌ็ๆฐๆฎๅบ้
็ฝฎ
const env = process.env.NODE_ENV //็ฏๅขๅๆฐ
//้
็ฝฎ
let MYSQL_CONF
if ( env === 'dev' ) {
MYSQL_CONF = {
host:"localhost",
port:"3306",
user:"root",
password:"xxx",
database:"myBlogs"
}
}
if ( env === 'production' ) {
MYSQL_CONF = {
host:"xxx.xxx.xxx.xxx",
port:"3306",
user:"root",
password:"xxx",
database:"myBlogs"
}
}
module.exports = {
MYSQL_CONF
}
# ๅๅปบdb/mysql.js ๅฏๅจnodeๅmysqlๅปบ็ซ่ฟๆฅ ๅฐ่ฃ
็ปไธๆง่กSQL็ๅฝๆฐdoSQL
const mysql = require('mysql');
const { MYSQL_CONF } = require('./conf');
const connection = mysql.createConnection(MYSQL_CONF);
connection.connect();
//็ปไธๆง่กsqlๅฝๆฐ
function doSQL(sql){
const promise = new Promise((resolve,reject)=>{
connection.query(sql,(err,res)=>{
if(err) reject(err);
resolve(res);
})
});
return promise;
}
module.exports = {
doSQL
}
# controllers/blogs.js ไฝฟ็จSQL็ญๆฐๆฎๅบๆไฝ๏ผๅฏนๅๆฐๆฎ่ฟ่กๆฟๆข --- ๅๅฎขๅ่กจ
const { doSQL } = require('../db/mysql');
/**
* ่ทๅๅๅฎขๅ่กจๆฐๆฎ GET
* http://localhost:8000/api/blog/list
* http://localhost:8000/api/blog/list?author=zhangsan
* http://localhost:8000/api/blog/list?author=zhangsan&keyword=A
*/
const getList = (author,keyword) => {
console.log(author,keyword);
let sql = `select * from blogs where 1=1`
if(author){
sql += ` and author='${author}'`
}
if(keyword){
sql += ` and title like '%${keyword}%'` //ๆณจๆand ๅ้ข็็ฉบๆ ผ
}
sql += ` order by 'createtime' desc;` //ๆณจๆorder ๅ้ข็็ฉบๆ ผ
//่ฟๅpromise
return doSQL(sql);
}
/**
* ๆ นๆฎid่ทๅๅไธชๅๅฎข่ฏฆๆ
GET
* http://localhost:8000/api/blog/detail?id=1
* http://localhost:8000/api/blog/detail?id=2
*/
const getDetail = (id) => {
let sql = `select * from blogs where id=${id}`;
return doSQL(sql);
}
/**
* ๅๅปบๆฐ็ๅๅฎขๅ
ๅฎน POST
* http://localhost:8000/api/blog/new
* body ๅ
ๅฎน
{
"title":"ๅๅฎขxx",
"content":"ๅ
ๅฎนxx"
}
*/
const newBlog = (blogData = {}) => {
const { title,content,author} = blogData;
let createtime = Date.now();
let sql = `insert into blogs (title,content,createtime,author) values ('${title}','${content}',${createtime},'${author}');` //ๆณจๆๆง่ก้กบๅบ
return doSQL(sql).then(insertData=>{
console.log('insertData==>',insertData);
/*OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 3,
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0 }*/
return {
id:insertData.insertId //้่ฟinsertIdๆฅๅคๆญๆฏๅฆๅ ่ฝฝๆๅ
}
});
}
/**
* ๅๅปบๆฐ็ๅๅฎขๅ
ๅฎน POST
* http://localhost:8000/api/blog/update?id=3
* body ๅ
ๅฎน
{
"title":"ๅๅฎขxxxx",
"content":"ๅ
ๅฎนxxxxx"
}
*/
const updateBlog = (id,blogData = {}) => {
// id ่ฆๆดๆฐ็ๅๅฎขid
// blogData ๅๅฎขๅฏน่ฑก ๅ
ๅซtitle contentๅฏน่ฑก
console.log('update blog',id,blogData);
const { title , content } = blogData;
let sql = `update blogs set title='${title}', content='${content}' where id=${id};` //ๆณจๆ ,็ฉบๆ ผ content='${content}'
return doSQL(sql).then(updateRes=>{
if(updateRes.affectedRows > 0){ //ๆ นๆฎaffectedRows>0ๆฅๅคๆญๆฏๅฆๆดๆฐๆๅ
return true;
}
return false;
})
}
/**
* ๅๅปบๆฐ็ๅๅฎขๅ
ๅฎน POST
* http://localhost:8000/api/blog/del?id=3
*/
const delBlog = (id,author) => {
//id ่ฆๅ ้ค็ๅๅฎขid
let sql = `delete from blogs where id='${id}' and author='${author}';` //ๅฎๅ
จๆบๅถ๏ผไฟ่ฏไฝ่
ไธ่ด
return doSQL(sql).then(updateRes=>{
if(updateRes.affectedRows > 0){ //ๆ นๆฎaffectedRows>0ๆฅๅคๆญๆฏๅฆๅ ้คๆๅ
return true;
}
return false;
})
}
module.exports = {
getList,
getDetail,
newBlog,
updateBlog,
delBlog
}
# controllers/user.js ไฝฟ็จSQL็ญๆฐๆฎๅบๆไฝ๏ผๅฏนๅๆฐๆฎ่ฟ่กๆฟๆข --- ็จๆทๅ่กจ
const { doSQL } = require('../db/mysql');
/**
* ็จๆท็ปๅฝๆณจๅ
* http://localhost:8000/api/user/login
*
{
"username":"lisi",
"password":"45655"
}
*/
const loginCheck = (username,password) => {
let sql = `select username,realname from users where username='${username}' and password='${password}';`
return doSQL(sql).then(usersArr => {
return usersArr[0] || {}
})
}
module.exports = {
loginCheck
}
# routers/blogs ๅฏนๆฐๆฎ่ฟ่ก่ทฏ็ฑ่ฟๅๅค็ -- ๅๅฎขๅ่กจ
const {
getList,
getDetail,
newBlog,
updateBlog,
delBlog
} = require('../controllers/blog')
const { SuccessModel,ErrorModel } = require('../models')
const handleBlogRouter = (req,res) =>{
const method = req.method;
const path = req.path;
const query = req.query;
const id = query && query.id;
//่ทๅๅๅฎขๅ่กจ /api/blog/list
if( method==="GET" && path === "/api/blog/list"){
const { author , keyword } = query;
// if(author && keyword){
// // const resData = getList(author,keyword);
// // return new SuccessModel(resData);
// return getList(author,keyword).then(resData=>{
// return new SuccessModel(resData);
// })
// }else {
// return new ErrorModel('่ทๅๅๅฎขๅ่กจๅคฑ่ดฅ๏ผ่ฏทไผ ๆญฃ็กฎ็ๅๆฐ author & keyword');
// }
return getList(author,keyword).then(resData=>{
return new SuccessModel(resData);
})
}
//่ทๅไธ็ฏๅๅฎข็ๅ
ๅฎน /api/blog/detail
if( method==="GET" && path === "/api/blog/detail"){
if(id){
return getDetail(id).then(resData=>{
return new SuccessModel(resData);
})
}
}
//ๆฐๅขไธ็ฏๅๅฎข /api/blog/new
if( method==="POST" && path === "/api/blog/new"){
req.body.author = "zhangsan" ; //ๅๆฐๆฎ๏ผTODO๏ผ็ปๅฝๆณจๅ
return newBlog(req.body).then(resData=>{
return new SuccessModel(resData);
});
}
//ๆดๆฐไธ็ฏๅๅฎข /api/blog/update
if( method==="POST" && path === "/api/blog/update"){
return updateBlog(id,req.body).then(resData=>{
if(resData){
return new SuccessModel('ๆดๆฐๅๅฎขๆๅ');
}else {
return new ErrorModel('ๆดๆฐๅๅฎขๅคฑ่ดฅ')
}
});
}
//ๅ ้คไธ็ฏๅๅฎข /api/blog/del
if( method==="POST" && path === "/api/blog/del"){
req.body.author = "zhangsan" ; //ๅๆฐๆฎ๏ผTODO๏ผ็ปๅฝๆณจๅ
return delBlog(id,req.body.author).then(resData=>{
if(resData){
return new SuccessModel('ๅ ้คๅๅฎขๆๅ');
}else{
return new ErrorModel('ๅ ้คๅๅฎขๅคฑ่ดฅ');
}
});
}
}
module.exports = handleBlogRouter;
# routers/users ๅฏนๆฐๆฎ่ฟ่ก่ทฏ็ฑ่ฟๅๅค็ -- ็จๆทๅ่กจ
const { loginCheck } = require('../controllers/user');
const { SuccessModel,ErrorModel } = require('../models')
const handleUserRouter = (req,res) =>{
const method = req.method;
const path = req.path;
//่ทๅๅๅฎขๅ่กจ /api/user/login
if( method==="POST" && path === "/api/user/login"){
const { username,password } = req.body;
return loginCheck(username,password).then(loginRes => {
if(loginRes.username){
return new SuccessModel('็ป้ๆๅ!');
}
return new ErrorModel('็ปๅฝๅคฑ่ดฅ!');
});
}
}
module.exports = handleUserRouter;
# app.js ๅฏน็ปๆ่ฟ่กๅ็ซฏ่ฟๅ
const queryString = require('querystring');
const handleBlogRouter= require('./routers/blog');
const handleUserRouter = require('./routers/user');
//่งฃๆpost data๏ผ่ฟๅpromiseๅฏน่ฑก
const getPostData = (req) => {
const promise = new Promise((resolve,reject) => {
if(req.method === "POST" && req.headers['content-type'] === 'application/json'){
let postData = "";
req.on('data',chunk => postData += chunk.toString());
req.on("end",()=>{
if(postData){
resolve(JSON.parse(postData));
}else{
resolve({});
return;
}
})
}else{
resolve({});
return;
}
});
return promise;
}
const serverHandle = (req,res) => {
//่ฎพ็ฝฎ่ฟๅ็JSON
res.setHeader('Content-type','application/json');
//่ทๅpath
const url = req.url;
req.path = url.split('?')[0];
req.query = queryString.parse(url.split('?')[1])
//่งฃๆpostๆฐๆฎ
getPostData(req).then(postData => {
req.body = postData;
//ๅค็ๅๅฎข็่ทฏ็ฑ
// const blogData = handleBlogRouter(req,res);
// if(blogData){
// res.end(JSON.stringify(blogData));
// }
const blogRes = handleBlogRouter(req,res);
if(blogRes){
blogRes.then(blogData=>{
res.end(JSON.stringify(blogData));
});
return;
}
//ๅค็็จๆท็ปๅฝ็่ทฏ็ฑ
// const userData = handleUserRouter(req,res);
// if(userData){
// res.end(JSON.stringify(userData));
// }
const userRes = handleUserRouter(req,res);
if(userRes){
userRes.then(userData=>{
res.end(JSON.stringify(userData));
});
return;
}
})
}
module.exports = serverHandle;
1.ไปไนๆฏcookie
- ๅญๅจๅจๆต่งๅจ็ไธๆฎตๅญ็ฌฆไธฒ๏ผๆๅคง5k๏ผ
- ่ทจๅไธๅ ฑไบซ
- ๆ ผๅผๅฆ๏ผk1=v1;k2=v2;k3=v3; ๅฏๅญๅจ็ปๆๅๆฐๆฎ
- ๆฏๆฌกๅ้http่ฏทๆฑ๏ผไผๅฐ่ฏทๆฑๅ็cookieไธ่ตทๅ้็ปserver
- serverๅฏไปฅไฟฎๆนcookieๅนถ่ฟๅ็ปๆต่งๅจ
- ๆต่งๅจไธญไนๅฏ้่ฟjsไฟฎๆนcookie(้ๅถ)
2.jsๆไฝcookie๏ผๆต่งๅจไธญๆฅ็cookie
- ๅฎขๆท็ซฏๆฅ็cookieไธ็งๆนๅผ
- Chromeๆงๅถๅฐ---> Network--->่ฏทๆฑไธญ็Request Header
- Chromeๆงๅถๅฐ---> Application --> Storage -->Cookies
- Chromeๆงๅถๅฐ---> Console --->่พๅ ฅ 'document.cookie'(jsๆฅ็)
- jsไฟฎๆนcookie(ๆ้ๅถ) - document.cookie='k1=100;' - document.cookie='k2=100;' - cookieไผ็ดฏๅ --> ็ปๆ: document.cookie --> "k1=100;k2=100;"
3.server็ซฏๆไฝcookie๏ผๅฎ็ฐ็ปๅฝ้ช่ฏ
- ๆฅ็cookie -- req.headers.cookie
- ไฟฎๆนcookie -- res.setHeader('Set-Cookie',
key1=v1;key2=v2;path=/) - ๆจกๆๅฎ็ฐ็ปๅฝ้ช่ฏ ๅ็๏ผ้่ฟget่ฏทๆฑ่พๅ ฅ่ดฆๅทๅๅฏ็ ๏ผ็ฌฌไธๆฌก็ป้ๅฎ๏ผserver็ซฏๅจๅฎขๆท็ซฏ็งไธไธชcookie๏ผๅฆๆไธๆฌกๅ็ปๅฝ๏ผRequest Header้ไผๆบๅธฆไธๆฌก็cookie
//ๅจserverHandleๅฝๆฐ้ ่งฃๆcookie
req.cookie = {}; //ๆ่ฝฝๅจreqไธ
const cookieStr = req.headers.cookie || ''; // k1=v1;k2=v2;
cookieStr.split(';').forEach(item=>{
let key = item.split('=')[0] || "";
let value = item.split('=')[1] || "";
req.cookie[key] = value;
})
console.log('req.cookie',req.cookie);
const { loginCheck } = require('../controllers/user');
const { SuccessModel,ErrorModel } = require('../models')
const handleUserRouter = (req,res) =>{
const method = req.method;
const path = req.path;
//่ทๅๅๅฎขๅ่กจ /api/user/login
if( method==="GET" && path === "/api/user/login"){ //่ฟ้ไฟฎๆนไธบGETๆฅๆจกๆ
// const { username,password } = req.body;
const { username,password } = req.query;
return loginCheck(username,password).then(loginRes => {
if(loginRes.username){
res.setHeader('Set-Cookie',`username=${loginRes.username};path=/;`)
return new SuccessModel('็ป้ๆๅ!');
}
return new ErrorModel('็ปๅฝๅคฑ่ดฅ!');
});
}
}
module.exports = handleUserRouter;
# test URL: http://localhost:8000/api/user/login?username=zhangsan&password=123
ไผๅจๆต่งๅจ็งไธไธชcookie
Response Header:
Connection: keep-alive
Content-Length: 37
Content-type: application/json
Date: Tue, 30 Jul 2019 14:11:56 GMT
Set-Cookie: username=zhangsan;path=/; # ่ฟไธชๆฏๆๅก็ซฏ็งไธ็
# ๅๆฌก่ฏทๆฑ
Request Header:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
Cookie: username=zhangsan #่ฟ้ไผๆบๅธฆไธๆฌก็งไธ็็cookie
Host: localhost:8000
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
4.cookieๅฎๅ จๆง 4.1 httpOnly ๅบๆฏ๏ผๅฏนไบ็ปๅฝ็lisi๏ผๅฆๆ้่ฟๅ็ซฏไฟฎๆนdocument.cookie="zhangsan"๏ผไผๅฏผ่ดzhangsan็ๆฐๆฎๆณๆผ๏ผไธบไบ้ฒๆญข่ฟ็งๆ ๅต๏ผๆๅก็ซฏ้่ฆ่ฟ่กๅฎๅ จ้ๅถ๏ผ้ฒๆญขๅ็ซฏไฟฎๆนcookie
# ่ฎพ็ฝฎhttpOnly
res.setHeader('Set-Cookie',`username=${loginRes.username};path=/; httpOnly`);
4.2 ่ฎพ็ฝฎcookie่ฟๆๆถ้ด ๅบๆฏ:ๅฏนไบ้ฟๆถ้ด็ปๅฝ็็ถๆ๏ผ้่ฆๅฎๆถ่ฎฉ็จๆท็ปๅฝ๏ผ้ฒๆญขไปไบบ่ทๅ็ปๅฝๅ็็จๆทไฟกๆฏ
//่ฎพ็ฝฎcookie่ฟๆๆถ้ด GMTๆ ผๅผ
const setCookieExpires = () => {
const date = new Date();
date.setTime(date.getTime() + (24*60*60*1000));
return date.toGMTString();
}
res.setHeader('Set-Cookie',`username=${loginRes.username};path=/; httpOnly; expires=${setCookieExpires()}`);
- ็ฅ้cookie็ๅฎไนๅ็น็น
- ๅๅ็ซฏๅฆไฝๆฅ็ๅไฟฎๆนcookie
- ๅฆไฝไฝฟ็จcookieๅฎ็ฐ็ปๅฝ้ช่ฏ
- ่งฃๅณๆนๆก๏ผcookieไธญๅญๅจuserid๏ผserver็ซฏๅฏนๅบusername๏ผ
- ๅ็ session๏ผๅณserver็ซฏๅญๅจ็จๆทไฟกๆฏ๏ผserver็ซฏ็ปๅฎขๆท็ซฏcookie็งไธไธชๅชๆserver็ซฏ่ฎค่ฏ็userid๏ผๆ นๆฎ่ฟไธชๅป้ช่ฏusernameๆฏๅฆๆฏไธไธชไบบ
# ๆ ธๅฟๅฎ็ฐไปฃ็ ไปฃ็ ไธๅๆไปถๅๆง่ก้กบๅบ
const SESSION_DATA = {}; //ๅญๅจsession
//ๆ นๆฎcookie่งฃๆsession
let userId = req.cookie.userid;
let needSetCookie = false;
if(userId){ //ๅคๆญๆฏๅฆๅทฒ็ปๆuserId,ๆฅๅณๅฎๆฏๅฆๆฏๅไธไธช็จๆท ๆๆฏ ๅจๅ็ซฏ็งไธไธช่ชๅทฑ่ฝ่ฏๅซ็userid
if(!SESSION_DATA[userId]){ //่กจ็คบๆuserid๏ผไฝๆฏๆฒกๆๆพๅฐๅฏนๅบ็username็ญๆฐๆฎ,ๆธ
็ฉบๅญๅจๅฝๅuserid็จๆท็ๅฏน่ฑก
SESSION_DATA[userId] = {};
}
} else { //ๅจๅ็ซฏ็งไธไธช่ชๅทฑ่ฝ่ฏๅซ็userid
needSetCookie = true;
userId = `${Date.now()}_${Math.random()}`;
SESSION_DATA[userId] = {};
}
/**
* ๅญๅจๅฝๅ็จๆท็userId ๆฐๆฎ็ปๆๆฏ
* SESSION_DATA = {
* 1:{username:xxx,relaname:xxx},
* 2:{username:xxx,relaname:xxx},
* '1565508588565_0.41190501274115565': { username: 'zhangsan', realname: 'ๅผ ไธ' }
* }
*/
req.session = SESSION_DATA[userId];
console.log('SESSION_DATA',SESSION_DATA);
//ๆ นๆฎๅ้้็useridๆฅๅคๆญๆฏๅฆๅจๅ็ซฏ็งcookie
if(needSetCookie){
res.setHeader('Set-Cookie',`userid=${userId};path=/; httpOnly; expires=${setCookieExpires()}`);
}
//่ฎพ็ฝฎsession๏ผๆ็ดขๆฐๆฎๅบ๏ผๅฐ็ๅฎ็็จๆทๅๅuseridๅฏนๅบ
if(loginRes.username){
// res.setHeader('Set-Cookie',`username=${loginRes.username};path=/; httpOnly; expires=${setCookieExpires()}`);
req.session.username = loginRes.username;
req.session.realname = loginRes.realname;
console.log('req.session is', req.session);
return new SuccessModel('็ป้ๆๅ!');
}
# app.jsๅฎๆดไปฃ็
const queryString = require('querystring');
const handleBlogRouter= require('./routers/blog');
const handleUserRouter = require('./routers/user');
const SESSION_DATA = {}; //ๅญๅจsession
//่ฎพ็ฝฎcookie่ฟๆๆถ้ด GMTๆ ผๅผ
const setCookieExpires = () => {
const date = new Date();
date.setTime(date.getTime() + (24*60*60*1000));
return date.toGMTString();
}
//่งฃๆpost data๏ผ่ฟๅpromiseๅฏน่ฑก
const getPostData = (req) => {
const promise = new Promise((resolve,reject) => {
if(req.method === "POST" && req.headers['content-type'] === 'application/json'){
let postData = "";
req.on('data',chunk => postData += chunk.toString());
req.on("end",()=>{
if(postData){
resolve(JSON.parse(postData));
}else{
resolve({});
return;
}
})
}else{
resolve({});
return;
}
});
return promise;
}
const serverHandle = (req,res) => {
//่ฎพ็ฝฎ่ฟๅ็JSON
res.setHeader('Content-type','application/json');
//่ทๅpath
const url = req.url;
req.path = url.split('?')[0];
//่งฃๆquery
req.query = queryString.parse(url.split('?')[1])
//่งฃๆcookie
req.cookie = {};
const cookieStr = req.headers.cookie || ''; // k1=v1;k2=v2;
cookieStr.split(';').forEach(item=>{
if(!item) return;
const arr = item.split('=');
const key = arr[0].trim() || "";
const value = arr[1].trim() || "";
req.cookie[key] = value;
})
console.log('req.cookie',req.cookie);
//ๆ นๆฎcookie่งฃๆsession
let userId = req.cookie.userid;
let needSetCookie = false;
if(userId){ //ๅคๆญๆฏๅฆๅทฒ็ปๆuserId,ๆฅๅณๅฎๆฏๅฆๆฏๅไธไธช็จๆท ๆๆฏ ๅจๅ็ซฏ็งไธไธช่ชๅทฑ่ฝ่ฏๅซ็userid
if(!SESSION_DATA[userId]){ //่กจ็คบๆuserid๏ผไฝๆฏๆฒกๆๆพๅฐๅฏนๅบ็username็ญๆฐๆฎ,ๆธ
็ฉบๅญๅจๅฝๅuserid็จๆท็ๅฏน่ฑก
SESSION_DATA[userId] = {};
}
} else { //ๅจๅ็ซฏ็งไธไธช่ชๅทฑ่ฝ่ฏๅซ็userid
needSetCookie = true;
userId = `${Date.now()}_${Math.random()}`;
SESSION_DATA[userId] = {};
}
/**
* ๅญๅจๅฝๅ็จๆท็userId ๆฐๆฎ็ปๆๆฏ
* SESSION_DATA = {
* 1:{username:xxx,relaname:xxx},
* 2:{username:xxx,relaname:xxx},
* '1565508588565_0.41190501274115565': { username: 'zhangsan', realname: 'ๅผ ไธ' }
* }
*/
req.session = SESSION_DATA[userId];
console.log('SESSION_DATA',SESSION_DATA);
//่งฃๆpostๆฐๆฎ
getPostData(req).then(postData => {
req.body = postData;
//ๅค็ๅๅฎข็่ทฏ็ฑ
// const blogData = handleBlogRouter(req,res);
// if(blogData){
// res.end(JSON.stringify(blogData));
// }
const blogRes = handleBlogRouter(req,res);
if(blogRes){
blogRes.then(blogData=>{
if(needSetCookie){
res.setHeader('Set-Cookie',`userid=${userId};path=/; httpOnly; expires=${setCookieExpires()}`);
}
res.end(JSON.stringify(blogData));
});
return;
}
//ๅค็็จๆท็ปๅฝ็่ทฏ็ฑ
// const userData = handleUserRouter(req,res);
// if(userData){
// res.end(JSON.stringify(userData));
// }
const userRes = handleUserRouter(req,res);
if(userRes){
userRes.then(userData=>{
if(needSetCookie){
res.setHeader('Set-Cookie',`userid=${userId};path=/; httpOnly; expires=${setCookieExpires()}`);
}
res.end(JSON.stringify(userData));
});
return;
}
})
}
module.exports = serverHandle;
# user.jsๅฎๆดไปฃ็
const { loginCheck } = require('../controllers/user');
const { SuccessModel,ErrorModel } = require('../models');
//่ฎพ็ฝฎcookie่ฟๆๆถ้ด GMTๆ ผๅผ
const setCookieExpires = () => {
const date = new Date();
date.setTime(date.getTime() + (24*60*60*1000));
return date.toGMTString();
}
const handleUserRouter = (req,res) =>{
const method = req.method;
const path = req.path;
//่ทๅๅๅฎขๅ่กจ /api/user/login
if( method==="GET" && path === "/api/user/login"){
// const { username,password } = req.body;
const { username,password } = req.query;
return loginCheck(username,password).then(loginRes => {
if(loginRes.username){
// res.setHeader('Set-Cookie',`username=${loginRes.username};path=/; httpOnly; expires=${setCookieExpires()}`);
req.session.username = loginRes.username;
req.session.realname = loginRes.realname;
console.log('req.session is', req.session);
return new SuccessModel('็ป้ๆๅ!');
}
return new ErrorModel('===>็ปๅฝๅคฑ่ดฅ!');
});
}
//ๆต่ฏ๏ผ้่ฟsessionๆฅ็ปๅฝ้ช่ฏ
if( method==="GET" && path === "/api/user/login-test"){
console.log('login-test,req.session==>',req.session);
console.log('login-test,req.cookie==>',req.cookie);
if(req.session.username){
return Promise.resolve(
new SuccessModel({
session:req.session
})
);
}
return Promise.resolve(new ErrorModel('็ปๅฝๅคฑ่ดฅ===>!'));
}
}
module.exports = handleUserRouter;
็ฎๅsession ็ดๆฅๆฏjsๅ้๏ผๆพๅจnodejs่ฟ็จๅ ๅญไธญ(Node่ฟ็จๆ้)
- ็ฌฌไธ๏ผ่ฟ็จๅ ๅญๆ้๏ผ่ฎฟ้ฎ้่ฟๅคง๏ผๅ ๅญๆดๅขๆไนๅ๏ผ(็จๆท่ฎฟ้ฎๅฆๆๅขๅค)
- ็ฌฌไบ๏ผๆญฃๅผ็บฟไธ่ฟ่กๆฏๅค่ฟ็จ็๏ผ่ฟ็จไน้ดๅ ๅญๆ ๆณๅ ฑไบซ(ๅฝๅ็จๆท1็ๆฐๆฎๅญๅจ่ฟ็จ1๏ผไฝๆฏๅฆๆไธๆฌก่ฎฟ้ฎ็จๆท1,่ฟๅฐ้่ฟ็จ2๏ผ่ฟ็จ2ไธๅญๅจ็จๆท1็ๆฐๆฎ๏ผๅฐฑไผๅฏผ่ด่ฟ็จ2้ๅคๅๅปบๆฐๆฎ)
่งฃๅณๆนๆก--redis
- web serverๆๅธธ็จ็็ผๅญๆฐๆฎๅบ๏ผๆฐๆฎๅญๅจๅจๅ ๅญไธญ
- ็ธๆฏไบmysql๏ผ่ฎฟ้ฎ้ๅบฆๅฟซ(ๅ ๅญๅ็กฌ็ๆฐๆฎๅบไธๆฏไธไธชๆฐ้็บง)
- ไฝๆๆฌๆด้ซ๏ผๅฏๅญๅจ็ๆฐๆฎ้ๆดๅฐ(ๅ ๅญ็็กฌไผค)
- ๅฐweb serverๅredisๆๅๆไธคไธชๅ็ฌ็ๆๅก(ๅ ณ้ฎ!!!)
- ๅๆน้ฝๆฏ็ฌ็ซ็๏ผ้ฝๆฏๅฏๆฉๅฑ็(ไพๅฆ ้ฝๆฉๅฑๆ้็พค)
- ๅ ๆฌmysql๏ผไนๆฏไธไธชๅ็ฌ็ๆๅก๏ผไนๅฏๆฉๅฑ
ไธบไปไนsession้็จredis๏ผ
- session่ฎฟ้ฎ้ข็น๏ผๅฏนๆง่ฝ่ฆๆฑๆ้ซ
- sessionๅฏไธ่่ๆญ็ตไธขๅคฑๆฐๆฎ็้ฎ้ข
- sessionๆฐๆฎ้ไธไผๅคชๅคง
ไธบไปไน็ฝ็ซๆฐๆฎไธ้ๅ็จredis๏ผ
- ๆไฝ้ข็ไธๆฏๅคช้ซ
- ๆญ็ตไธ่ฝไธขๅคฑ๏ผๅฟ ้กปไฟ็
- ๆฐๆฎ้ๅคชๅคง๏ผๅ ๅญๆๆฌๅคช้ซ
windowsๅฎ่ฃ
redis
Macๅฎ่ฃ
brew install redis
# redisไฝฟ็จ
redis-server #ๅฏๅจๆๅก
redis-cli # ๆฐๅปบ็ชๅฃ
set key1 value1 # ่ฎพ็ฝฎkey:value
get key1 # ่ทๅkey็ๅผ
keys * # ่ทๅๆๆkey
del key1 # ๅ ้คๅฝๅkey
npm install redis --save
const redis = require('redis');
//ๅๅปบๅฎขๆท็ซฏ
const redisClient = redis.createClient(6379,'127.0.0.1');
redisClient.on('error',err=>{
console.log(err);
});
//test-่ฎพ็ฝฎๅผ๏ผๅๅผ
redisClient.set('myname','zhangsan2',redis.print);
redisClient.get('myname',(err,val)=>{
if(err){
console.error(err);
return;
}
console.log('val',val);
redisClient.quit();
});
node index.js # ้่ฟnode่ฟๆฅredis ่ฏปๅๆไฝ
Reply: OK
val zhangsan2
# redisๅฎขๆท็ซฏๆฅ็ๆฏๅฆ็ๆkey
redis-cli
127.0.0.1:6379> keys *
1) "myname"
##### db/conf.js #####
let REDIS_CONF;
if ( env === 'dev' ) {
REDIS_CONF = {
host:'127.0.0.1',
port:6379
}
}
if ( env === 'production' ) {
REDIS_CONF = {
host:'127.0.0.1',
port:6379
}
}
module.exports = {
REDIS_CONF
}
##### db/redis.js ๅฐ่ฃ
get & set ๆนๆณ #####
const redis = require('redis');
const { REDIS_CONF } = require('./conf');
const { port , host } = REDIS_CONF;
//ๅๅปบๅฎขๆท็ซฏ
const redisClient = redis.createClient(port,host);
redisClient.on('error',err => {
console.error(err);
});
//ๅฐ่ฃ
redis setๆนๆณ
function redisSet(key,val){
if(typeof val === 'object'){
val = JSON.stringify(val);
}
redisClient.set(key,val,redis.print);
}
//ๅฐ่ฃ
redis getๆนๆณ
function redisGet(key){
const promise = new Promise((resolve,reject) =>{
redisClient.get(key,(err,val) =>{
if(err){
reject(err);
return;
}
if(val === null){
resolve(null);
return;
}
try {
resolve(JSON.parse(val)); //try/catch ไธๆฏไธบไบๆๅผๅธธ,่ๆฏๅ
ผๅฎนๅฏน่ฑก็ๅผ
}catch(e){
resolve(val);
}
});
});
return promise;
}
module.exports = {
redisSet,
redisGet
}
##### app.js #######
const { redisSet, redisGet } = require('./db/redis');
//ๅฐsessionๅญๅจๅฐredisไธญ
let userId = req.cookie.userid;
let needSetCookie = false;
if(!userId){
needSetCookie = true;
userId = `${Date.now()}_${Math.random()}`;
redisSet(userId,{});
}
// ่ทๅๅฝๅuseridๅฏนๅบ็username๏ผrelaname
req.sessionId = userId;
redisGet(req.sessionId).then(sessionData => {
if(sessionData == null){
redisSet(req.sessionId,{});
req.session = {};
} else {
req.session = sessionData;
}
});
##### routers/user.js #####
const { redisSet } = require('../db/redis');
req.session.username = loginRes.username;
req.session.realname = loginRes.realname;
redisSet(req.sessionId,req.session);
# router/blog.js
const {
getList,
getDetail,
newBlog,
updateBlog,
delBlog
} = require('../controllers/blog');
const { SuccessModel,ErrorModel } = require('../models');
// ๆฐๅข๏ผ็ปไธ็ปๅฝ้ช่ฏๅฝๆฐ
const loginCheck = (req) => {
if(!req.session.username){
return Promise.resolve(
new ErrorModel('ๅฐๆช็ปๅฝ')
)
}
}
//ๆฐๅข๏ผ้ช่ฏๆฏๅฆ็ปๅฝ
const loginCheckResFunc = (req) => {
const loginCheckRes = loginCheck(req);
if(loginCheckRes){
return loginCheckRes;
}
}
const handleBlogRouter = (req,res) =>{
const method = req.method;
const path = req.path;
const query = req.query;
const id = query && query.id;
//่ทๅๅๅฎขๅ่กจ /api/blog/list
if( method==="GET" && path === "/api/blog/list"){
const { author , keyword } = query;
return getList(author,keyword).then(resData=>{
return new SuccessModel(resData);
})
}
//่ทๅไธ็ฏๅๅฎข็ๅ
ๅฎน /api/blog/detail
if( method==="GET" && path === "/api/blog/detail"){
if(id){
return getDetail(id).then(resData=>{
return new SuccessModel(resData);
})
}
}
//ๆฐๅขไธ็ฏๅๅฎข /api/blog/new
if( method==="POST" && path === "/api/blog/new"){
loginCheckResFunc(req); //ๆฐๅข
req.body.author = req.session.username; //ๆฐๅข๏ผไธๅๆฏๅๆฐๆฎ
return newBlog(req.body).then(resData=>{
return new SuccessModel(resData);
});
}
//ๆดๆฐไธ็ฏๅๅฎข /api/blog/update
if( method==="POST" && path === "/api/blog/update"){
loginCheckResFunc(req); //ๆฐๅข
return updateBlog(id,req.body).then(resData=>{
if(resData){
return new SuccessModel('ๆดๆฐๅๅฎขๆๅ');
}else {
return new ErrorModel('ๆดๆฐๅๅฎขๅคฑ่ดฅ')
}
});
}
//ๅ ้คไธ็ฏๅๅฎข /api/blog/del
if( method==="POST" && path === "/api/blog/del"){
loginCheckResFunc(req); //ๆฐๅข
req.body.author = req.session.username; //ๆฐๅข
return delBlog(id,req.body.author).then(resData=>{
if(resData){
return new SuccessModel('ๅ ้คๅๅฎขๆๅ');
}else{
return new ErrorModel('ๅ ้คๅๅฎขๅคฑ่ดฅ');
}
});
}
}
module.exports = handleBlogRouter;
# routers/user.js
const { loginCheck } = require('../controllers/user');
const { SuccessModel,ErrorModel } = require('../models');
const { redisSet } = require('../db/redis');
const handleUserRouter = (req,res) =>{
const method = req.method;
const path = req.path;
//่ทๅๅๅฎขๅ่กจ /api/user/login
if( method==="POST" && path === "/api/user/login"){
const { username,password } = req.body;
return loginCheck(username,password).then(loginRes => {
if(loginRes.username){
req.session.username = loginRes.username;
req.session.realname = loginRes.realname;
redisSet(req.sessionId,req.session);
return new SuccessModel('็ป้ๆๅ!');
}
return new ErrorModel('็ปๅฝๅคฑ่ดฅ!');
});
}
}
module.exports = handleUserRouter;
- ็ปๅฝๅ่ฝไพ่ตcookie๏ผๅฟ ้กป็จๆต่งๅจๆฅ่่ฐ
- cookie่ทจๅไธๅ ฑไบซ๏ผๅ็ซฏๅserver็ซฏๅฟ ้กปๅๅ
- ้่ฆ็จๅฐnginxๅไปฃ็๏ผ่ฎฉๅๅ็ซฏๅๅ
- admin.html
- edit.html
- login.html
- detail.html
- index.html
- new.html
npm install http-server -g
http-server -p 8001 # ๅๅปบๅ็ซฏ้ๆ่ตๆบๆๅก็ซฏๅฃๅทไธบ8001,ๅฏๆฅ็ๅ็ซฏhtmlๆไปถ
- ๅ็ซฏ็ซฏๅฃ๏ผ8001
- ๅ็ซฏ็ซฏๅฃ๏ผ8000
nginxไป็ป
- ้ซๆง่ฝ็webๆๅกๅจ๏ผๅผๆบๅ ่ดน
- ไธ่ฌ็จไบๅ้ๆๆๅก๏ผ่ด่ฝฝๅ่กก
- ๅๅไปฃ็
- ๆญฃๅไปฃ็:ๅฎขๆท็ซฏๆงๅถ็ไปฃ็
- ๅๅไปฃ็๏ผๅฏนไบๅฎขๆท็ซฏๆฏไธไธช้ป็็server็ซฏไปฃ็
nginxๅๅไปฃ็
- ๆต่งๅจ---> localhost/index.html ---> nginx ---> / ---> html
- ๆต่งๅจ---> localhost/index.html ---> nginx ---> /api/... ---> nodejs
nginxไธ่ฝฝ
Windows
Mac brew install nginx
nginx้ ็ฝฎ Windows:C:\nginx\conf\nginx.conf Mac:/usr/local/etc/nginx/nginx.conf
nginxๅฝไปค
nginx -t # ๆต่ฏ้
็ฝฎๆไปถๆ ผๅผๆฏๅฆๆญฃ็กฎ
nginx -s reload # ๅฏๅจnginx ้ๅฏ
nginx -s stop # ๅๆญข
# vim /usr/local/etc/nginx/nginx.conf
worker_processes 2; # ๅฏๅจๅ ไธชๅ
ๆ ธ
location / {
proxy_pass http://localhost:8001;
}
location /api/ {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
}
# nginx -t ๆต่ฏๆฏๅฆ้
็ฝฎไปฃ็ๆๅ
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
- cookieๆฏไปไน๏ผ sessionๆฏไปไน๏ผๅฆไฝๅฎ็ฐ็ปๅฝ๏ผ
- redisๆฎๆผไปไน่ง่ฒ๏ผๆไปไนๆ ธๅฟไปทๅผ๏ผ
- nginx็ๅๅไปฃ็้ ็ฝฎ๏ผ่่ฐ่ฟ็จไธญ็ไฝ็จ๏ผ
- ็ณป็ปๆฒกๆๆฅๅฟ๏ผๅฐฑ็ญไบไบบๆฒกๆ็ผ็
- ๆฏๆฅๆต้๏ผ QPSๅคๅฐ(QPS:ๆฏ็ง่ฎฟ้ฎ้)๏ผ
- ็ฌฌไธ๏ผ่ฎฟ้ฎๆฅๅฟ access log (server็ซฏๆ้่ฆ็ๆฅๅฟ)
- ๅฎขๆท็ซฏไฟกๆฏ,้กต้ขไฟกๆฏ
- GET/POST ่ฏทๆฑ
- ๆต่งๅจไฟกๆฏ,ๅ ๆฏ
- ็ฌฌไบ๏ผ่ชๅฎไนๆฅๅฟ(ๅ ๆฌ่ชๅฎไนไบไปถใ้่ฏฏ่ฎฐๅฝ็ญ);
- ๆไน่ฎฐๅฝๆฅๅฟ๏ผ
- ๆไนๆๅๆฅๅฟ๏ผๅๆๆฅๅฟ๏ผ
1.็ฎๅฝ
- Nodejs ๆไปถๆไฝ --- Stream ๆต(ไธบไบ่็CPUๅ
ๅญ)
- ๆฅๅฟ่ฆๅญๅจๅฐๆไปถไธญ -- ้่ฆๆท่ดๅฐๅ ถไปๆไปถ๏ผๅๅฐๆไฝๆๆฌ
- ไธบไฝไธๅญๅจๅฐmysqlไธญ๏ผ -- ็กฌ็ๆฐๆฎๅบ๏ผ้ๅๅค่กจ่ๅจ็ๆฅ่กจๆไฝๅบๆฏ
- ไธบไฝไธๅญๅจๅฐredisไธญ๏ผ -- ๅ ๅญๆฐๆฎๅบ๏ผๆๆฌๅคช้ซ๏ผๆฅๅฟๆไฝไธ้ข็น
- ๆฅๅฟๅ่ฝๅผๅๅไฝฟ็จ
- ๆฅๅฟๆไปถๆๅ๏ผๆฅๅฟๅ ๅฎนๅๆ
2.ๆไปถ่ฏปๅ๏ผๆฏๅฆๅญๅจ
- fs.readFile
- fs.writeFile
- fs.exist
3.IOๆไฝ็ๆง่ฝ็ถ้ข
- IO ๅ ๆฌ"็ฝ็ปIO" ๅ "ๆไปถIO"
- ็ธๅฏนไบCPU่ฎก็ฎๅๅ ๅญ่ฏปๅ๏ผIO็็ชๅบ็น็นๅฐฑๆฏ๏ผๆ ข๏ผ
- ๅฆไฝๅจๆ้็็กฌไปถ่ตๆบไธๆ้ซIO็ๆไฝๆ็๏ผ
4.stream--่งฃๆพCPUๅ ๅญ
- ๆ ๅ่พๅ ฅ่พๅบ๏ผpipeๅฐฑๆฏ็ฎก้๏ผ็ฌฆๅๆฐดๆต็ฎก้็ๆจกๅๅพ๏ผ
- process.stdin่ทๅๆฐๆฎ๏ผ็ดๆฅ้่ฟ็ฎก้ไผ ้็ป process.stdout
process.stdin.pipe(process.stdout)
node index.js
### ็ปๆ ่พๅ
ฅ123 ๅ่ฝฆๅฐฑๆฏๅฏนๅบ็ๅ
ๅฎน
123
123
231231231
231231231
- ๆไปถIOๆไฝ
# ๅฐ 1.txtๆไปถๅ
ๅฎน ๅคๅถๅฐ 2.txt
const fs = require('fs');
const path = require('path');
const filename1 = path.resolve(__dirname,'./1.txt');
const filename2 = path.resolve(__dirname,'./2.txt');
const readStream = fs.createReadStream(filename1);
const writeStream = fs.createWriteStream(filename2);
//ๅฐๆไปถ1.txt็ๅ
ๅฎน้่ฟๆต็ๆนๅผ ๅคๅถๅฐ 2.txt
readStream.pipe(writeStream);
//็ๅฌๅๅ
readStream.on('data',chunk => {
console.log(chunk.toString());
});
readStream.on('end',() => {
console.log('copy done');
});
- ็ฝ็ปIOๆไฝ
# ็ฝ็ปIOๆไฝ,ๅฐ1.txtๆๆฌๅ
ๅฎน้่ฟๆต่ฟๅ่ณๅฎขๆท็ซฏ
const http = require('http');
const fs = require('fs');
const path = require('path');
//ๅฐๆไปถ1็ๅ
ๅฎน้่ฟstream่พๅบ่ฟๅ่ณๅฎขๆท็ซฏ -- 1
const filename1 = path.resolve(__dirname,'./1.txt');
const server = http.createServer((req,res)=>{
if(req.method === "GET"){
const readStream = fs.createReadStream(filename1); //2
readStream.pipe(res); //3
}
})
server.listen(8005);
# utils/log.js
const fs =require('fs');
const path = require('path');
//็ๆwrite stream
function createWriteStream(fileName){
const fullFileName = path.resolve(__dirname,'./','../','logs',fileName);
const writeStream = fs.createWriteStream(fullFileName,{
flags:'a' //append ่ฟฝๅ ๅๆฅๅฟ
});
return writeStream;
}
const accessWriteStream = createWriteStream('access.log');
function writeLog(writeStream,log){
writeStream.write(log + '\n'); //ๅ
ณ้ฎ
}
function access(log){
writeLog(accessWriteStream,log);
}
module.exports = {
access
}
# ไฝฟ็จ
const { access } = require('./utils/log');
//่ฎฐๅฝ access log
access(`${req.method} -- ${req.url} -- ${req.headers['user-agent']} -- ${Date.now()}`);
- ๆฅๅฟๅ ๅฎนไผๆ ขๆ ข็งฏ็ดฏ๏ผๆพๅจไธไธชๆไปถไธญไธๅฅฝๅค็
- ๆๆถ้ดๅๅๆฅๅฟๆไปถ๏ผๅฆ 2019-08-13.access.logs
- ๅฎ็ฐๆนๅผ: linux็crontabๅฝไปค,ๅณๅฎๆถไปปๅก
- ่ฎพ็ฝฎๅฎๆถไปปๅก ๆ ผๅผ *****command ==> minute/hour/day/month/week command ้กบๅบ๏ผๅ ๆถ ๆฅ ๆ ๅจ shell่ๆฌ ไพๅฆ
5****command ่กจ็คบ ๆฏ5ๅ้ๆง่ก่ฏฅๅฝไปค
*1***command ่กจ็คบ ๆฏๅคฉ็็ฌฌ1ไธชๅฐๆถๆง่ก่ฏฅๅฝไปค
**5**command ่กจ็คบ ๆฏไธชๆ5ๅทๆง่ก่ฏฅๅฝไปค
***5*command ่กจ็คบ 5ๆ1ๅทๆง่ก่ฏฅๅฝไปค
****5command ่กจ็คบ ๆฏๅจ5ๆง่ก่ฏฅๅฝไปค
ๅๆฏๅฆ
## ๅ้ ##
* * * * * command ๆฏ1ๅ้ๆง่กไธๆฌกcommand
3,15 * * * * command ๆฏๅฐๆถ็็ฌฌ3ๅ็ฌฌ15ๅ้ๆง่ก
## ๅฐๆถ ##
* */1 * * * /etc/init.d/smb restart ๆฏไธๅฐๆถ้ๅฏsmb
* 23-7/1 * * * /etc/init.d/smb restart ๆไธ11็นๅฐๆฉไธ7็นไน้ด๏ผๆฏ้ไธๅฐๆถ้ๅฏsmb
30 21 * * * /etc/init.d/smb restart ๆฏๆ็21:30้ๅฏsmb
0,30 18-23 * * * /etc/init.d/smb restart ๆฏๅคฉ18 : 00่ณ23 : 00ไน้ดๆฏ้30ๅ้้ๅฏsmb
3,15 8-11 * * * command ๅจไธๅ8็นๅฐ11็น็็ฌฌ3ๅ็ฌฌ15ๅ้ๆง่ก
## ๆฅๆ ##
3,15 8-11 */2 * * command ๆฏ้ไธคๅคฉ็ไธๅ8็นๅฐ11็น็็ฌฌ3ๅ็ฌฌ15ๅ้ๆง่ก
45 4 1,10,22 * * /etc/init.d/smb restart ๆฏๆ1ใ10ใ22ๆฅ็4 : 45้ๅฏsmb
## ๆไปฝ ##
0 4 1 jan * /etc/init.d/smb restart ไธๆไธๅท็4็น้ๅฏsmb
## ๅจ ##
3,15 8-11 * * 1 command ๆฏไธชๆๆไธ็ไธๅ8็นๅฐ11็น็็ฌฌ3ๅ็ฌฌ15ๅ้ๆง่ก
10 1 * * 6,0 /etc/init.d/smb restart ๆฏๅจๅ
ญใๅจๆฅ็1:10้ๅฏsmb
0 11 4 * mon-wed /etc/init.d/smb restart ๆฏๆ็4ๅทไธๆฏๅจไธๅฐๅจไธ็11็น้ๅฏsmb
- ๅฐaccess.logๆท่ดๅนถ้ๅฝๅไธบ2019-11-2.access.log
- ๆธ ็ฉบaccess.logๆไปถ๏ผ็ปง็ปญ็งฏ็ดฏๆฅๅฟ
#### ็ผๅshell่ๆฌ ####
#!/bin/sh
cd /Users/yuxiaoyang03/Desktop/learning/Node-Blog/blog-1/logs // ๅฐlog็็ฎๅฝไธ
cp access.log $(date +%Y-%m-%d).access.log // ๅฐaccess.logๆ นๆฎๆถ้ดๆฅๆ้ๅฝๅ
echo "" > access.log // ๆธ
็ฉบaccess.log
#### ่ฎพ็ฝฎๅฎๆถไปปๅก ####
crontab -e
#### ็ผๅๅฎๆถไปปๅก ๆฏๅคฉๅๆจ0็น0ๅๆง่กshell่ๆฌ ####
* 0 * * * sh /Users/yuxiaoyang03/Desktop/learning/Node-Blog/blog-1/utils/copyLog.sh
#### ๆฅ็ๅทฒ็ป่ฎพ็ฝฎ็ๅฎๆถไปปๅก ####
crontab -l
- ๅฆ้ๅฏนaccess.logๆฅๅฟ๏ผๅๆChrome็ๅ ๆฏ
- ๆฅๅฟๆฏๆ่กๅญๅจ็๏ผไธ่กๅฐฑๆฏไธๆกๆฅๅฟ
- ไฝฟ็จNode็readline(ๅบไบstream๏ผๆ็้ซ)
// readlineไฝฟ็จๆญฅ้ชค
const readline = require('readline');
const fileName = path.join(__dirname, '../logs/access.log'); //ๆพ่ฆๅๆ็ๆฅๅฟ
const readStream = fs.createReadStream(fileName); // ๅๅปบreadstream
const rl = readline.createInterface({
input: readStream
});// ๅๅปบreadlineๅฏน่ฑก
rl.on('line',()=>{});
rl.on('close',()=>{});
- ๅฐ http://localhost:8000/api/blog/list ๅจChrome/Safari/Firefox้้ขๆง่กๅ ้ๅจaccess.log้ไบง็ๆฅๅฟๅ ๅฎน
- ๅๅปบ utils/readline.js
const fs = require('fs');
const path = require('path');
const readline = require('readline');
// ๅฏปๆพ็ฎๆ ๆฅๅฟๆไปถ
const fileName = path.join(__dirname, '../logs/access.log');
// ๅๅปบ่ฏปๅๆต
const readStream = fs.createReadStream(fileName);
// ๅๅปบreadlineๅฏน่ฑก
const rl = readline.createInterface({
input: readStream
});
// ่ฎกๆฐๅจ
let chromeNum = 0;
let sum = 0;
// ้่ก่ฏปๅ
rl.on('line', (lineData) => {
if (!lineData) {
return;
};
sum++;
// ่ทๅChromeๆต่งๅจ็ๆฅๅฟไฟกๆฏ
// GET -- /api/blog/list -- Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36 -- 1572693248592
let logArr = lineData.split(' -- '); // ๆ นๆฎ--ๆฅๅฟๆ ผๅผๆๅ
if (logArr[2] && logArr[2].indexOf('Chrome') > 0) {
chromeNum++;
}
});
rl.on('close', () => {
let res = parseFloat(chromeNum / sum).toFixed(2) * 100 + "%";
console.log('chromeๆต่งๅจๅ ๆฏ:' + res);
});
- ๆง่ก node ./utils/readline.js
- ๆฅๅฟๅฏนไบserver็ซฏๅพ้่ฆ๏ผๅฐฑๅ็ผ็
- IOๆง่ฝ็ถ้ข๏ผไฝฟ็จstreamๆ้ซๆง่ฝ
- ไฝฟ็จcrontabๆๅๆฅๅฟๆไปถ
- ไฝฟ็จreadlineๅๆๆฅๅฟๅ ๅฎน
- SQLๆณจๅ ฅ:็ชๅๆฐๆฎๅบๅ ๅฎน
- XSSๆปๅป:็ชๅๅ็ซฏ็cookie็ๅ ๅฎน
- ๅฏ็ ๅ ๅฏ:ไฟๆค็จๆทไฟกๆฏๅฎๅ จ(้่ฆ๏ผ๏ผ)
- ๆๅๅงใๆ็ฎๅ็ๆปๅป๏ผไปweb2.0ๅฐฑๆไบ
- ๆปๅปๆนๅผ:่พๅ ฅไธไธชsql็ๆฎต๏ผๆ็ปๆผๆฅๆไธๆฎตๆปๅปไปฃ็
- ้ข้ฒๆชๆฝ:ไฝฟ็จmysql็escapeๅฝๆฐๅค็่พๅ ฅๅ ๅฎนๅณๅฏ
# ๆญฃๅธธ็sql
select username,realname from users where username='zhangsan'and password='123';
# ๅฆๆๅจ็จๆทๅๅค่พๅ
ฅ โzhangsan' --โ ๅฐฑไผๅฏผ่ดsqlๆณจๅ
ฅ
select username,realname from users where username='zhangsan' -- 'and password='123';
# ่ฟๆ ทๅ ไธโ'zhangsan;delete from users -- โๅฐฑๅฎ่ไบ users่กจๅฐฑๆฒกไบ
select username,realname from users where username='zhangsan';delete from users -- 'and password='123';
# ้ฒ่ -- ๅฉ็จmysql.escape()
username = mysql.escape(username)
password = mysql.escape(password)
## escape่ฝฌไนไบ็ฌฆๅท ๆไปฅ่พพๅฐไบ้ฒๆญขsqlๆณจๅ
ฅ็ๅ่ฝ
select username,realname from users where username='zhangsan\' -- 'and password='123';
- ๅ็ซฏๅๅญฆๆ็ๆ็ๆปๅปๆนๅผ๏ผไฝserver็ซฏๆดๅบ่ฏฅๆๆก
- ๆปๅปๆนๅผ:ๅจ้กต้ขๅฑ็คบๅ ๅฎนไธญๆบๆjsไปฃ็ ๏ผไปฅ่ทๅ็ฝ้กตไฟกๆฏ
- ้ข้ฒๆชๆฝ:่ฝฌๆข็ๆjs็็นๆฎๅญ็ฌฆ
// xssๆปๅป ๅพๆๆฌๆก้่พๅ
ฅjsไปฃ็
<script>alert(document.cookie)</script>
// ่ฝฌๆข็นๆฎๅญ็ฌฆ
& --> &
< --> ⁢
> --> >
" --> "
' --> '
/ --> /
// ๅฏไปฅๅฎ่ฃ
xssๅทฅๅ
ทๅ
npm i xss --save
title = xss(title);
content = xss(content);
- ๆฐๆฎๅบ่ขซ็จๆทๆป็ ด๏ผๆไธๅบ่ฏฅๆณๆผ็ๅฐฑๆฏ็จๆทไฟกๆฏ
- ๆปๅปๆนๅผ:่ทๅ็จๆทๅๅๅฏ็ ,ๅๅปๅฐ่ฏ็ปๅฝๅ ถไป็ณป็ป
- ้ข้ฒๆชๆฝ:ๅฐๅฏ็ ๅ ๅฏ๏ผๅณไพฟๆฟๅฐๅฏ็ ไนไธๆพ็คบๆๆ
// ๅ็: ่ชๅฎไน็key + ๅฏ็ --> ๅ ๅฏ็ๆณ
let SELECT_KEY = 'AbcD_123123##';
let content = `password=${password}&key=${SELECT_KEY}`;
let md5Pass = crypto.createHash('md5').update(content).digest('hex'); //ๆ็ปๅ ๅฏ็ๅฏ็
// ๅฐzhangsan็ๅฏ็ ๆดๆฐไธบๅ ๅฏไนๅ็'eb0c2f011e4adb48ad2802321a8c132f'
// ๆดๆขๅฏ็ ้ฟๅบฆ ๅณๅปusers่กจ --> Alter Table --> VARCHAR(20) ๆนไธบ VARCHAR(32)
-
ๅผๅไบๅชไบๅ่ฝๆจกๅ๏ผๅฎๆด็ๆต็จ
- ๅ่ฝๆจกๅ
- ๅค็httpๆฅๅฃ
- ่ฟๆฅๆฐๆฎๅบ
- ๅฎ็ฐ็ปๅฝ
- ๅฎๅ จ
- ๆฅๅฟ
- ไธ็บฟ
- ๆต็จ ๆต่งๅจ ---> nginx ---> /.. ---> ้ๆๆไปถhtml/css/js/img ---> /api/.. ---> ๆฅๅฟ่ฎฐๅฝ(ๆฅๅฟๆไปถ)/่ทฏ็ฑๅค็/็ป้ๆ ก้ช(redis)/็จๆทไฟกๆฏ(redis)/ๆฐๆฎๅค็(mysql)
- ๅ่ฝๆจกๅ
-
็จๅฐไบๅชไบๆ ธๅฟ็ฅ่ฏ็น
- http,nodejsๅค็httpใๅค็่ทฏ็ฑใmysql
- cookieใsessionใredisใnginxๅๅไปฃ็
- ๅฎๅ จ็ฅ่ฏ:sqlๆณจๅ ฅใxssๆปๅปใๅฏ็ ๅ ๅฏ
- ๆฅๅฟใstreamใcontrabใreadline
-
ๅ้กพ serverๅๅ็ซฏ็ๅบๅซ
- ๆๅก็จณๅฎๆง
- ๅ ๅญCPUไผๅๆฉๅฑ
- ๆฅๅฟ่ฎฐๅฝ
- ๅฎๅ จ(ๅ ๆฌ็ปๅฝ้ช่ฏ)
- ้็พคๅๆๅกๆๅ
- Nodejsๆๅธธ็จ็web server
- ไธ่ฝฝใๅฎ่ฃ ใไฝฟ็จใexpressไธญ้ดไปถๆบๅถ
- ๅผๅๆฅๅฃใ่ฟๆฅๆฐๆฎๅบใๅฎ็ฐ็ปๅฝใๆฅๅฟ่ฎฐๅฝ
- ๅๆexpressไธญ้ดไปถๅ็
- ๅฎ่ฃ
--express-generator่ๆๆถ
- sudo npm i express-generator -g
- express blog-express
- npm i & npm start
- npm i cross-env nodemon -D
- ๅๅงๅไปฃ็ ไป็ปใๅค็่ทฏ็ฑ
- ไฝฟ็จไธญ้ดไปถ
- ๅไธชๆไปถ็ไฝ็จ
- ๆ่ๆดๆไปถ็ๅฎ็ฐๅ็
- ๅค็get/post่ฏทๆฑ
- app.use(ไธญ้ดไปถๅฝๆฐ)
- app.get(ไธญ้ดไปถๅฝๆฐ)
- app.post(ไธญ้ดไปถๅฝๆฐ)
- npm i express-session
// app.js
const session = require('express-session');
app.use(session({
secret: 'AAAbbb_123##',
cookie: {
path: '/', //้ป่ฎค
httpOnly: true,//้ป่ฎค
maxAge: 24 * 60 * 60 * 100
}
}));
// user.js
/** ๆต่ฏsessionๆฏๅฆๆๅ
* http://localhost:3000/api/user/session-test
* ้่ฟๅจไธๅๆต่งๅจ็่ฟๅๅฏไปฅ็ๅฐไธๅ็ๆฐๅญ๏ผ่ฏดๆsession้
็ฝฎๆๅ
*/
router.get('/session-test',(req,res,next)=>{
const session = req.session;
if(!session.vieNum){
session.vieNum = 0
}
session.vieNum ++;
res.json({
vieNum:session.vieNum
})
})
ๅ็:็ป้ๅฎๅจๆๅก็ซฏ่ฎฐๅฝsession็จๆทไฟกๆฏ,ๅจ้่ฟlogin-test้ช่ฏๆฏๅฆๅทฒ็ปๅฝ
router.get('/login-get', function(req, res, next) {
const { username,password } = req.query;
return loginCheck(username,password).then(loginRes => {
if(loginRes.username){
req.session.username = loginRes.username;
req.session.realname = loginRes.realname;
res.json(new SuccessModel('็ป้ๆๅ!'));
return;
}
res.json(new ErrorModel('็ปๅฝๅคฑ่ดฅ!'));
});
});
/** ๆต่ฏ/loginๆฏๅฆๆๅ
* http://localhost:3000/api/user/login-get?username=zhangsan&password=123 ่ฟ้็จgetๆจกๆpost็ปๅฝ
* http://localhost:3000/api/user/login-test ๆต่ฏๆฏๅฆๅทฒ็ปๅฝ
*/
router.get('/login-test',(req,res,next)=>{
const session = req.session;
if(session.username){
res.json({
res:'ๅทฒ็ปๅฝ'
})
return
}
res.json({
res:'็ปๅฝๅคฑ่ดฅ'
})
});
// ๅฎ้
็ปๅฝไฝฟ็จ็ๆฏpost
router.post('/login', function(req, res, next) {
const { username,password } = req.body;
return loginCheck(username,password).then(loginRes => {
if(loginRes.username){
req.session.username = loginRes.username;
req.session.realname = loginRes.realname;
res.json(new SuccessModel('็ป้ๆๅ!'));
return;
}
res.json(new ErrorModel('็ปๅฝๅคฑ่ดฅ!'));
});
});
- npm i redis connect-redis
// 1 ่ทๅredisๅฎขๆท็ซฏ db/redis.js
const redis = require('redis');
const { REDIS_CONF } = require('./conf');
const { port , host } = REDIS_CONF;
//ๅๅปบๅฎขๆท็ซฏ
const redisClient = redis.createClient(port,host);
redisClient.on('error',err => {
console.error(err);
});
module.exports = redisClient;
// app.js ่ฟๆฅredis็่ฟ็จ
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const redisClient = require('./db/redis');
const sessionStore = new RedisStore({
client:redisClient
})
app.use(session({
store:sessionStore
}))
- ๆต่ฏredisไธญๆฏๅฆๅทฒ็ปๅญๅจไบ็จๆท็key
redis-cli
่ฎฟ้ฎ http://localhost:3000/api/user/login-get?username=zhangsan&password=123
keys *
127.0.0.1:6379> keys *
1) "sess:VKNIoVD6i8u6pTgksuzfCBOQEU67YDJt" # ่กจ็คบๅญ่ฟๅปไบ
# ่ทๅ็จๆทไฟกๆฏ
get sess:VKNIoVD6i8u6pTgksuzfCBOQEU67YDJt
"{\"cookie\":{\"originalMaxAge\":8640000,\"expires\":\"2019-11-03T11:49:33.851Z\",\"httpOnly\":true,\"path\":\"/\"},\"username\":\"zhangsan\",\"realname\":\"\xe5\xbc\xa0\xe4\xb8\x89\"}" ---> ็จๆทไฟกๆฏ
const ENV = process.env.NODE_ENV
if(ENV !== 'production'){
// ่งฃๆๅผๅ็ฏๅข ๆฅๅฟ
app.use(logger('dev'));
// GET /api/blog/list 304 10.089 ms - - ๆฅๅฟๆ ผๅผ
}else{
// ่งฃๆ็บฟไธ็ฏๅข ๆฅๅฟ
const logFile = path.join(__dirname,'./logs/access.log');
const writeStream = fs.createWriteStream(logFile,{
flags:'a'
});
app.use(logger('combined',{
stream:writeStream
}));
//::1 - - [03/Nov/2019:11:18:04 +0000] "GET /api/blog/list HTTP/1.1" 304 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
}
- expressไธญ้ดไปถๆฏๅผๆญฅๅ่ฐ๏ผkoa2ๅ็ๆฏๆasync/await
- ๆฐๆกๆถๅผๅๆกๆถๅ็ณป็ป๏ผ้ฝๅบไบkoa2๏ผไพๅฆegg.js
- aysnc/await ่ฏญๆณไป็ป ๅฎ่ฃ ๅไป็ปkoa2
- ๅผๅๆฅๅฃ๏ผ่ฟๆฅๆฐๆฎๅบ๏ผๅฎ็ฐ็ปๅฝ๏ผๆฅๅฟ่ฎฐๅฝ
- ๅๆkoa2ไธญ้ดไปถๅ็
- aysnc ๅฝๆฐๆง่ก่ฟๅpromiseๅฏน่ฑก
- await ๅ ๅฏๆง่กpromiseๅฏน่ฑก
- await ๅฟ ้กปๅ ่ฃนๅจ asyncๅฝๆฐๅ
- try-catchๅฏไปฅๆช่ทpromiseไธญreject็ๅผ
async function getRes() {
try {
const aData = await getFileContent('1.json');
console.log(aData);
const bData = await getFileContent(aData.next);
console.log(bData);
const cData = await getFileContent(bData.next);
console.log(cData);
} catch (err) {
console.error(err);
}
}
getRes()
- ๅฎ่ฃ
ไฝฟ็จkoa-generator
- npm i koa-generator
- Koa2 my-test
- npm i & npm run dev
- npm i cross-env ่ๆๆถๆฒกๆ้ ็ฝฎ็ฏๅขๅๆฐ๏ผ้่ฆๆๅจ้ ็ฝฎ
"dev": "cross-env NODE_ENV=dev ./node_modules/.bin/nodemon bin/www",
"prd": "cross-env NODE_ENV=production pm2 start bin/www",
-
ๅๅงๅไปฃ็ ๅค็่ทฏ็ฑ
- ctx ไธไธๆ --> req,res็้ๅ
- ๅค็่ทฏ็ฑ ่ฎฟ้ฎ http://localhost:8000/api/user
// routes/user.js const router = require('koa-router')() router.prefix('/api/user') router.get('/', async (ctx, next) => { ctx.body ={ title:'123' } }) module.exports = router// app.js const user = require('./routes/user'); // ๅผๅ ฅ่ทฏ็ฑๆไปถ app.use(user.routes(), user.allowedMethods()); // ๆณจๅ่ทฏ็ฑ -
ไฝฟ็จไธญ้ดไปถ
-
ๅฎ็ฐ็ปๅฝ
- koa-gengeric-session ๅ koa-redis
- npm i koa-generic-session koa-redis redis
// app.js const session = require('koa-generic-session'); const redisStore = require('koa-redis'); // connect redis to save session info app.keys = ['AAAbbb_123##']; app.use(session({ store: redisStore({ all:'127.0.0.1:6379' //ๆฌๅฐๅๆญป }), // ้ ็ฝฎcookie cookie: { path: '/', httpOnly: true, maxAge: 24 * 60 * 60 * 1000 } }))- redis-server ๅผๅฏredisๆๅก
- ็ผๅๆต่ฏsession็ไปฃ็
// routes/user.js router.get('/session-test', async (ctx, next) => { if (ctx.session.vieNum == null) { ctx.session.vieNum = 0 } ctx.session.vieNum++; ctx.body = { vieNum: ctx.session.vieNum } })- ๆง่กhttp://localhost:8000/api/user/session-testๅจๆต่งๅจไธญๆต่ฏ
- ๅจredisไธญๆฅ็ๆฏๅฆๅญๅ
ฅ
redis-cli
127.0.0.1:6379> keys *
- "koa:sess:e9n3c4mZ8zvjmkAr_FXGPhcT-DM9GVb_" 127.0.0.1:6379> get "koa:sess:e9n3c4mZ8zvjmkAr_FXGPhcT-DM9GVb_" "{"cookie":{"path":"/","httpOnly":true,"maxAge":86400000,"overwrite":true,"signed":true},"vieCount":1,"vieNum":3}"
-
ๅผๅๆฅๅฃ
- user็จๆท็ปๅฝๆๅ
ณ
- http://localhost:8000/api/user/login ็จๆท็ปๅฝ { "username":"lisi", "password":"45655" }
- blog็ธๅ
ณ
- http://localhost:8000/api/blog/list ่ทๅๅๅฎขๅ่กจๆฐๆฎ
- http://localhost:8000/api/blog/detail?id=1 ๆ นๆฎid่ทๅๅไธชๅๅฎข่ฏฆๆ
- http://localhost:8000/api/blog/new ๅๅปบๆฐ็ๅๅฎขๅ ๅฎน POST { "title":"ๅๅฎขxx", "content":"ๅ ๅฎนxx" }
- http://localhost:8000/api/blog/update?id=2 ๆดๆฐๅๅฎขๅ ๅฎน POST { "title":"ๅๅฎขxxxx", "content":"ๅ ๅฎนxxxxx" }
- http://localhost:8000/api/blog/del?id=3 ๆ นๆฎidๅ ้คๅๅฎขๅ ๅฎน POST
- user็จๆท็ปๅฝๆๅ
ณ
-
่ฎฐๅฝๆฅๅฟ -- ็ปง็ปญไฝฟ็จmorgan
- ไฝฟ็จkoa-smorgan
- ่ชๅฎไนๆฅๅฟไฝฟ็จconsole.logๅconsole.error
- ๆฅๅฟๆไปถๆๅ
- ๆฅๅฟๅ ๅญๅๆ
POST /api/blog/update?id=2 - 34ms --> POST /api/blog/update?id=2 200 39ms 42b <-- GET /api/blog/list GET /api/blog/list - 2ms --> GET /api/blog/list 200 7ms 231b
const logger = require('koa-logger')
// logger
app.use(async (ctx, next) => {
const start = new Date()
await next()
const ms = new Date() - start
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})
- npm i koa-morgan
// app.js
const fs = require('fs');
const path = require('path');
const morgan = require('koa-morgan');
// use koa-mogran to save logs
const ENV = process.env.NODE_ENV
if (ENV !== 'production') { // ่งฃๆๅผๅ็ฏๅข ๆฅๅฟ ๆ ผๅผ:GET /api/blog/list 200 8.058 ms - 343
app.use(morgan('dev'));
}
else { // ่งฃๆ็บฟไธ็ฏๅข ๆฅๅฟ
const logFile = path.join(__dirname, './logs/access.log');
const writeStream = fs.createWriteStream(logFile, {
flags: 'a'
});
app.use(morgan('combined', {
stream: writeStream
}));
// ๆ็ป็บฟไธ็ๆฅๅฟๆ ผๅผ ::1 - - [06/Nov/2019:13:29:19 +0000] "GET /api/blog/list HTTP/1.1" 200 343 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"
}
// test09-koa-test
/** koa -- ๆด่ฑๅทๆจกๅ
1.....็ฌฌไธๅฑๆด่ฑ--ๅผๅง...
3.......็ฌฌไบๅฑๆด่ฑ--ๅผๅง.
5.......็ฌฌไธๅฑๆด่ฑ--ๅผๅง
6.......็ฌฌไธๅฑๆด่ฑ--็ปๆ
4.....็ฌฌไบๅฑๆด่ฑ--็ปๆ...
2.....็ฌฌไธๅฑๆด่ฑ--็ปๆ...
*/
- 1.app.useๆณจๅไธญ้ดไปถ ่ฟ่กๆถ้
- 2.ๅฎ็ฐnextๆบๅถ๏ผไธไธไธช้่ฟnext่งฆๅไธไธไธช
- 3.ไธๆถๅmethodๅpath
- ๆๅกๅจ็จณๅฎๆง
- ๅ ๅๅฉ็จๆๅกๅจ็กฌไปถ่ตๆบ๏ผไปฅไพฟๆ้ซๆง่ฝ
- ็บฟไธๆฅๅฟ่ฎฐๅฝ
- ่ฟ็จๅฎๆค๏ผ็ณป็ปๅดฉๆบ่ชๅจ้ๅฏ
- ๅฏๅจๅค่ฟ็จ๏ผๅ ๅๅฉ็จCPUๅๅ ๅญ
- ่ชๅธฆๆฅๅฟ่ฎฐๅฝๅ่ฝ
-
- pm2 start app.js
-
- pm2 list
-
- pm2 --version
-
- pm2 restart /
- ๅฆๆไฟฎๆนไบๆๅก้้ข็ๅ ๅฎน๏ผ้ๅฏๆๅกๅฏไปฅ็ดๆฅไฝฟ็จ pm2 restart 0 / app Use --update-env to update environment variables [PM2] Applying action restartProcessId on app [0](ids: [ '0' ]) [PM2] app โ
โโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโ
โ id โ name โ version โ mode โ pid โ uptime โ โบ โ status โ cpu โ mem โ user โ watching โ
โโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโผโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโค
โ 0 โ app โ 1.0.0 โ fork โ 53536 โ 0s โ 1 โ online โ 0% โ 13.1mb โ yuxโฆ โ disabled โ
โโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโดโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโ
-
- pm2 stop / [PM2] Applying action stopProcessId on app [app](ids: [ 0 ]) [PM2] app โ
โโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโ
โ id โ name โ version โ mode โ pid โ uptime โ โบ โ status โ cpu โ mem โ user โ watching โ
โโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโผโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโค
โ 0 โ app โ 1.0.0 โ fork โ 0 โ 0 โ 5 โ stopped โ 0% โ 0b โ yuxโฆ โ disabled โ
โโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโดโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโ
-
- pm2 delete / [PM2] Applying action deleteProcessId on app [app](ids: [ 0 ]) [PM2] app โ
-
- pm2 info / ๆฅ็ๆๅก็ไฟกๆฏ
-
- pm2 log / ๆฅ็ๆฅๅฟ
- 0|app | server is listen on port 7000
0|app | cur time 1573129491818
0|app | error 1573129491818
0|app | cur time 1573129491931
0|app | error 1573129491931
0|app | cur time 1573129493350
0|app | error 1573129493350
0|app | cur time 1573129493402
0|app | error 1573129493402
- cat /Users/.../.pm2/logs/app-error.log ๆฅ็้่ฏฏๆฅๅฟ
- cat /Users/.../.pm2/logs/app-out.log ๆฅ็่พๅบๆฅๅฟ
-
- pm2 monit / ๆฅ็ๅฝๅ้่ฟpm2่ฟ่ก็่ฟ็จ็็ถๆ๏ผๆฏๅฆๅ ๅญไฟกๆฏ,ๆฅๅฟ็ญ
โโ Process List โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ app Logs โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ[ 0] app Mem: 31 MB CPU: 0 % online โโ app > cur time 1573129746959 โ
โ โโ app > error 1573129746960 โ
โ โโ app > cur time 1573129747028 โ
โ โโ app > error 1573129747028 โ
โ โโ app > cur time 1573129747806 โ
โ โโ app > error 1573129747806 โ
โ โโ app > cur time 1573129747846 โ
| โโ app > error 1573129747846
// ๆจกๆ้่ฏฏ
if(req.url === '/err'){
throw new Error('error')
}
้ๅฏpm2 pm2 restart 0 ่ฎฟ้ฎ http://localhost:7000/err ้กต้ขๆๆ pm2 list
โโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโ
โ id โ name โ version โ mode โ pid โ uptime โ โบ โ status โ cpu โ mem โ user โ watching โ
โโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโผโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโค
โ 0 โ app โ 1.0.0 โ fork โ 54999 โ 0s โ 3 โ online โ 0% โ 10.8mb โ yuxโฆ โ disabled โ
โโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโดโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโ
โโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโ
โ id โ name โ version โ mode โ pid โ uptime โ โบ โ status โ cpu โ mem โ user โ watching โ
โโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโผโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโค
โ 0 โ app โ 1.0.0 โ fork โ 55041 โ 6s โ 5 โ online โ 2.3% โ 31.2mb โ yuxโฆ โ disabled โ
โโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโดโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโ
ๅ็ฐrestart็ฑ3 --> 5
- ๆฐๅปบPM2้ ็ฝฎๆไปถ(ๅ ๆฌ่ฟ็จๆฐ้๏ผๆฅๅฟๆไปถ็ฎๅฝ็ญ)
- ไฟฎๆนPM2ๅฏๅจๅฝไปค๏ผ้ๅฏ
- ่ฎฟ้ฎserver๏ผๆฃๆฅๆฅๅฟๆไปถ็ๅ ๅฎน(ๆฅๅฟ่ฎฐๅฝๆฏๅฆ็ๆ)
{
"apps":{
"name":"pm2-test-server",
"script":"app.js",
"watch":true,
"ignore_watch":[
"node_modules",
"logs"
],
"error_file":"logs/err.log", //ไฟฎๆนๆฅๅฟ็ฎๅฝ
"out_file":"logs/out.log",
"log_date_format":"YYYY-MM-DD HH:mm:ss"
}
}
// package.json
"prd:conf":"cross-env NODE_ENV=production pm2 start pm2.conf.json"
- ๆไฝ็ณป็ป้ๅถไธไธช่ฟ็จ็ๅ ๅญ
- ๅ ๅญ๏ผๆ ๆณๅ ๅๅฉ็จๆบๅจๅ จ้จๅ ๅญ
- CPU: ๆ ๆณๅ ๅๅฉ็จๅคๆ ธCPU็ไผๅฟ
- ๅค่ฟ็จไน้ด๏ผๆ ๆณๅฎ็ฐๅ ๅญๅ ฑไบซ
- ่งฃๅณ: ๅค่ฟ็จ่ฎฟ้ฎๅไธไธชredis,ๅฎ็ฐๆฐๆฎๅ ฑไบซ
// ๆทปๅ instancesๅฑๆง
{
"apps":{
"name":"pm2-test-server",
"script":"app.js",
"watch":true,
"ignore_watch":[
"node_modules",
"logs"
],
"error_file":"logs/err.log",
"out_file":"logs/out.log",
"log_date_format":"YYYY-MM-DD HH:mm:ss",
"instances":4
}
}
npm run prd:conf
โโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโ
โ id โ name โ version โ mode โ pid โ uptime โ โบ โ status โ cpu โ mem โ user โ watching โ
โโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโผโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโค
โ 0 โ pm2-test-server โ 1.0.0 โ cluster โ 56926 โ 27s โ 0 โ online โ 0% โ 33.3mb โ yuxโฆ โ enabled โ
โ 1 โ pm2-test-server โ 1.0.0 โ cluster โ 56927 โ 27s โ 0 โ online โ 0% โ 33.0mb โ yuxโฆ โ enabled โ
โ 2 โ pm2-test-server โ 1.0.0 โ cluster โ 56932 โ 27s โ 0 โ online โ 0% โ 32.0mb โ yuxโฆ โ enabled โ
โ 3 โ pm2-test-server โ 1.0.0 โ cluster โ 56935 โ 27s โ 0 โ online โ 0.3% โ 33.2mb โ yuxโฆ โ enabled โ
โโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโดโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโ
- ๆๅกๅจ่ฟ็ปด๏ผๆไธไธ็OPไบบๅๆฅๅค็
- ๅคงๅ ฌๅธๆ่ชๅทฑ็่ฟ็ปด
- ไธญๅฐๅๅ ฌๅธ๏ผๆจ่ไฝฟ็จ้ฟ้ไบ็ญไบๆๅก