debian7搭建生产环境的linux+nodejs+express+mysql的web服务器

标签: linux  nodejs

注:Windows使用ssh可以下载Putty,请自行百度搜索

 打开https://billing.virmach.com/register.php,注册账号

登录账号来到主界面,点击Serveces、View Available Addons,网址:https://billing.virmach.com/clientarea.php

选择自己想要购买的主机套餐 

这里我用debian7 

加入购物车 

付款成功后,点击My Services 

这时你会看到购买的主机状态是Active,否则你要找客服(找客服请点击右下角Live Support)

点击进入主机管理页面,找到IP

在终端输入以下命令远程登录服务器(Windows用putty)

ssh root@你的IP

 

 

终端提示要输入登录密码时,点击如图叹号将密码输入

输入密码回车,登录成功

 

 远程登录成功后,首先输入以下命令更新apt-get

apt-get update

以下命令可以查看Linux系统是32位还是64位 

getconf LONG_BIT

下载Nodejs,64位系统下载64位包,这里我们用wget下载

以下是wget安装命令,因为这个debian系统自带wget所以无需安装 

apt-get install wget

打开http://nodejs.cn/download

右键选择复制链接地址 

在终端输入以下命令下载nodejs

wget https://npm.taobao.org/mirrors/node/v10.7.0/node-v10.7.0-linux-x64.tar.xz

下载若发现以下问题

 

用以下命令安装便可 

wget --no-check-certificate https://npm.taobao.org/mirrors/node/v8.11.2/node-v8.11.2-linux-x64.tar.xz

wget --no-check-certificate https://nodejs.org/dist/v8.11.2/node-v8.11.2-linux-x64.tar.xz

下载成功后终端输入ls查看该文件 

 

输入以下命令解压nodejs压缩包,命令名字要与上图红线标识包名一致

tar xvJf node-v8.11.2-linux-x64.tar.xz

 以下命令将node-v8.11.2-linux-x64文件夹改名为node-v8.11.2

mv node-v8.11.2-linux-x64 node-v8.11.2

 

设置软连接

ln -s /root/node-v8.11.2/bin/node /usr/local/bin/node  
ln -s /root/node-v8.11.2/bin/npm /usr/local/bin/npm

输入以下命令 

node -v
npm -v

出现以下结果,表明Nodejs环境安装成功

 

将你的代码上传到服务器,比如我的代码(打开https://github.com/SemperChen/bookmark/archive/master.zip下载)

scp -r /Users/Semper/Documents/projects/bookmark [email protected]:root

windows可以使用WinSCP上传文件,下载地址:https://excellmedia.dl.sourceforge.net/project/winscp/WinSCP/5.13.3/WinSCP-5.13.3-Setup.exe

上传成功后在终端用ls查看 

安装pm2

npm install -g pm2

安装bookmark项目依赖库,cd是回到当前用户目录,也就是root

cd
cd bookmark
npm install

pwd可查询当前路径 

pwd

 以下是ecosystem.config.js文件代码

module.exports = {
  apps : [
    {
      //general
      name      : 'bookmark',
      script    : 'server.js', //启动执行的初始脚本

      //advanced
      watch     : ['appsback','routes','ecosystem.config.js','server.js'],//监听文件变化
      ignore_watch: ['node_modules','apps','static'],//忽略监听的文件夹
      max_memory_restart: '500M',//内存达到多少会自动restart
      env: {
        COMMON_VARIABLE: 'true'
      },
      env_production : {
        NODE_ENV: 'production'
      },

      //log file
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',//日志格式

      //control
      min_uptime: 3000,
      listen_timeout: 3000,
      kill_timeout: 5000,
      max_restarts: 5,
    }
  ]
};

安装MySQL 

apt-get install mysql-server mysql-client

MySQL差不多安装完成时,会提示输入新密码,需输入两次

 以下命令登录MySQL

mysql -uroot -p

 

 创建数据库test

CREATE DATABASE test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

使用test数据库 

use test

 创建表users

create table users{
    id INT(5) PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(18),
    password VARCHAR(50),
    bookmark TEXT
};

 建表成功

在bookmark目录下,启动pm2

pm2 start ecosystem.config.js --env production

开机启动 

pm2 startup

 

启动成功后:

注册账号测试http://107.173.35.226:8000/register?username=张三&password=123456&bookmark=[1,2,3] 

登录账号测试http://107.173.35.226:8000/login?username=张三&password=123456

如果无法访问尝试开放8000端口 

iptables -A INPUT -p tcp --dport 8000 -j ACCEPT

server.js代码:

let express = require('express');
let url = require('url');
let app = express();
let mysql  = require('mysql');

let connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : '123456',
    port: '3306',
    database: 'test',
});

connection.connect();
app.get('/login', function (req, res) {
    // res.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    // userDao.updateUser(connection,'菜鸟工具21','111111book2123123');
    let params = url.parse(req.url, true).query;
    login(params,res)

})
function login(params,res) {
    let  sql = 'SELECT * FROM users WHERE username="'+params.username+'"';
//查
    connection.query(sql,function (err, result) {
        if(err){
            // console.log('[SELECT ERROR] - ',err.message);
            // return;
        }
        // console.log('result',result,'err',err,);
        if(result.length===1&&result[0].username===params.username&&result[0].password===params.password){
            res.send({isLogin:true,msc:'登录成功!',user:result[0]});
        }else {
            res.send({isLogin:false,msc:'登录失败!用户名或密码错误'});
        }

    });
}
app.get('/register', function (req, res) {
    let params = url.parse(req.url, true).query;
    register(params,res)

})
function register(params,res) {
    let  sql = 'SELECT * FROM users WHERE username="'+params.username+'"';
//查
    connection.query(sql,function (err, result) {
        if(err){
            // console.log('[SELECT ERROR] - ',err.message);
            // return;
        }
        // console.log('result',result,'err',err,);
        if(result.length===0){
            let  addSql = 'INSERT INTO users(username,password,bookmark) VALUES(?,?,?)';
            let  addSqlParams = [params.username, params.password, params.bookmark];
//增
            connection.query(addSql,addSqlParams,function (err, result) {
                if(err){
                    console.log('[INSERT ERROR] - ',err.message);
                    return;
                }
                login(params,res)
            });
        }else {
            res.send({isRegisterSuccess:false,msc:'注册失败,用户名已存在!'});
        }

    });
}
function saveBookmark(params,res) {
    let  sql = 'SELECT * FROM users WHERE username="'+params.username+'"';
//查
    connection.query(sql,function (err, result) {
        if(err){
            // console.log('[SELECT ERROR] - ',err.message);
            // return;
        }
        // console.log('result',result[0],'err',err,);
        if(result.length===1&&result[0].username===params.username&&result[0].password===params.password){
            let modSql = 'UPDATE users SET bookmark = ? WHERE username = ?';
            let modSqlParams = [params.bookmark,params.username];
//改
            connection.query(modSql,modSqlParams,function (err, result) {
                if(err){
                    // console.log('[UPDATE ERROR] - ',err.message);
                    // return;
                }
                res.send({isSavedBookmark:true,isLogin:true,msc:'已同步到云书架!',user:params});
            });
        }else {
            res.send({isSavedBookmark:true,msc:'保存失败!'});
        }

    });
}
app.get('/save', function (req, res) {
    let params = url.parse(req.url, true).query;
    saveBookmark(params,res)

})

// connection.end();
let server = app.listen(8000, function () {
    let host = server.address().address;
    let port = server.address().port;

    // console.log("应用实例,访问地址为 http://%s:%s", host, port)

})

 package.json:

{
  "name": "bookmark",
  "version": "0.0.0",
  "private": true,
  "scripts": {},
  "dependencies": {
    "express": "^4.16.2",
    "mysql": "^2.15.0"
  }
}

 

版权声明:本文为chensenp原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chensenp/article/details/81189912

智能推荐

CSS盒模型

盒子模型 盒子模型是什么 CSS盒子模型就是在CSS技术所使用的一种思维模型。CSS假定所有的HTML文档元素都生成一个描述该元素在HTML文档布局中所占空间的矩形元素框,可以形象地将其看作是一个盒子。通过定义一系列与盒子相关的属性,可极大地丰富和促进各个盒子乃至整个HTML文档的表现效果和布局结构。CSS盒子模型由内容区、填充、边框和空白边四部分组成。内容区是盒子模型的中心,呈现盒子的主要信息内...

通用分页

通用分页 我们从数据库里面拿到的数据要进行分页首先需要连接到数据库 这些类是不能少的;这是获得数据库对象的类 pageBean 首先我们需要把想要分页的属性进行一个封装,一个分页的工具类 BookDao 然后我们需要一个dao方法 ,就以BookDao 为案列 我们需要继承baseDao通用dao方法进行一个分页实现(BaseDao在后面) BaseDao 这个是通用的dao方法 实体类进行分页实...

VS2013调试X64平台时出现MSVSMON.EXE failed to start的问题

1.问题 vs2013突然有一天调试X64平台程序时出现“Visual Studio Remote Debugging Monitor(MSVSMON.EXE)failed to start”的问题,如下图所示。如果切换为X86平台可以编译通过。网上搜了好多方法都没有解决问题。              ...

HTTP与HTTPS的区别

原创 天才程序YUAN 最后发布于2020-03-22 00:00:29 阅读数 886 收藏 发布于2020-03-22 00:00:29 分类专栏: 实习 收起 《计算机网络自顶向下方法》学习专栏 涵盖《计算机网络自顶向下方法》的知识点,实验和经典习题。按内容可分为计算机网络概述、应用层、传输层、网络层和数据链路层。实验包括HTTP 代理服务器的设计与实现、GBN 协议的设计与实现、利用 Wi...

【Docker】win10上修改docker的镜像文件存储位置(九)- 通过WSL2修改

闲话少说 软件版本 window 10 v1909 小版本号 Docker Desktop Installer v20.10.0( 细致版本看下图) 安装过程所遇 官网下载的docker.exe直接安装即可,安装中间选项,直接安装的C盘下(C:\Program Files\Docker),由上面的docker info可看出,docker的默认路径(/var/lib/docker)跟linux一样...

猜你喜欢

Netty 中的心跳检测机制

心跳检测一般存在于建立长连接 或者 需要保活的场景。 心跳的使用场景 长连接的应用场景非常的广泛,比如监控系统,IM系统,即时报价系统,推送服务等等。像这些场景都是比较注重实时性,如果每次发送数据都要进行一次DNS解析,建立连接的过程肯定是极其影响体验。 而长连接的维护必然需要一套机制来控制。比如 HTTP/1.0 通过在 header 头中添加 Connection:Keep-Alive参数,如...

Halcon视觉轮廓线拟合测量-@龙熙视觉培训

Halcon基础**** ——带你进入图像处理的世界 1.方法1 轮廓线拟合测量 1.1.测量1–Measure pump * step: create and select relevant contours * threshold_sub_pix (ImageReduced, Border, 80) select_shape_xld (Border, Sel...

一、python爬虫学习第一天(request初级)

爬虫获取数据的基本步骤: 1、获取指定页面的url 2、模拟发起请求 3、获取响应的数据 4、持久化存储 第一个模拟需求,爬取搜狗首页数据,简单get请求,不带参数不带数据。 数据爬取成功 第二个模拟需求,爬取搜狗指定词条相对应得页面,带简单参数和ua。 数据爬取成功 第三个需求 ,爬取百度翻译(post),带简单数据和ua,以及ajax的json数据获取以及存储。 数据存储成功 第四个模拟需求,...

HashMap、HashTable、JDK1.7 ConcurrentHashMap源码分析 比较

众所周知,哈希表是非常高效,复杂度为O(1)的数据结构,在Java开发中,我们最常见到最频繁使用的就是HashMap和HashTable,但是在线程竞争激烈的并发场景中使用都不够合理。   HashMap :先说HashMap,HashMap是线程不安全的,在并发环境下,可能会形成环状链表(扩容时可能造成,具体原因自行百度google或查看源码分析),导致get操作时,cpu空转,利用率可能达到1...