1. 程式人生 > >NestJS折騰記- (0) 開胃菜, TypeORM 連線遠端的MySQL(ssh tunnel)及Linux資訊過濾裁切基礎

NestJS折騰記- (0) 開胃菜, TypeORM 連線遠端的MySQL(ssh tunnel)及Linux資訊過濾裁切基礎

前言

昨天發現的框架,看了下官方文件,號稱Nodejs版本的spring(java)

開發模式有ng6既視感,這對有ng經驗的小夥伴來說,莫名的親切..

適合嚐嚐鮮,目前有1W+ star, 上正式線我覺得等version 6會穩定些,

這個系列我會以一個真實專案的開發進展作為基礎,一邊爬坑一邊水文;

後臺大佬用的PHP,我打算用空閒時間拿nestjs重寫我們後臺管理系統提供的那部分介面

其他就不多說了

官網 | NestJS迭代計劃(roadmap)


效果圖

失敗

失敗的原因有那麼幾個;

  • 資料庫的配置資訊跟實際要連結的資料庫資料不一致(比如資料庫名字,比如使用者名稱密碼)
  • 隧道轉發的埠給本地其他服務佔用了,比如mysql本地啟動的(預設3306)
    • 這時候要麼改埠對映,要麼關閉本地資料庫
  • ts語法錯誤

成功


程式碼

db.ts(src/config)

溫馨提示: 若是要用__dirname,確保配置檔案在根目錄,否則請改用相對路徑,不然會找不到實體

synchronize是同步,會自動同步到資料庫,比如建表什麼的(根據實體)


import { join } from 'path';
const EntityRecursivePath = join('..'
, '/**/*.entity{.ts,.js}'); export const MySqlConfig: any = { type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: '!=basestagging**', database: 'shengxi_v2', entities: [EntityRecursivePath], synchronize: true, }; 複製程式碼

app.module.ts

UsersModule 裡面寫了對應的服務,實體的關聯


import
{ Module, NestModule, MiddlewareFunction } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; // 使用者模組,註冊,登入,更新個人資訊 import { UsersModule } from './modules/users/users.module'; // 資料庫ORM import { TypeOrmModule } from '@nestjs/typeorm'; import { MySqlConfig } from './config/db'; @Module({ imports: [TypeOrmModule.forRoot(MySqlConfig), UsersModule], controllers: [AppController], providers: [AppService], }) export class AppModule implements NestModule { // consumer 這裡可以掛在中介軟體什麼的 configure(consumer: MiddlewareFunction): void { consumer .apply(null) .with('AppModule') .forRoutes('/'); } } 複製程式碼

users.entity.ts


import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

// entity裝飾器提供一個options可以配置關聯的表名,引擎等等,具體看她的interface
// 不提供name的話,,類名就是表名了

@Entity({
  name: 'sx_admin',
})
export class Users {
  @PrimaryGeneratedColumn() id: number;

  // 使用者名稱
  @Column('varchar', { length: 100 })
  admin_name: string;

  // 使用者密碼
  @Column('varchar', { length: 255 }) admin_passwd: string;

  // 建立時間
  @Column('timestamp') created_at: number;
  // 更新時間
  @Column('timestamp') updated_at: number;
  // 是否啟用
  @Column('int') admin_status: number;
}


複製程式碼

剩下的姿勢,就在services裡面注入實體和ormRepository;

再到controller注入服務呼叫即可...返回的是Promise


要點提示及溫馨提示

SSH隧道轉發(SSH Tunnel)

遠端資料庫我們一般不暴露外接埠直連,安全隱患太高;

一般選擇走ssh 隧道(很常用的接入方式),

通過ssh登入認證伺服器,再轉發本地的埠到遠端埠,達到資料打通的姿勢

  • ssh命令轉發

ssh的命令解釋(官方手冊): 英文,寫的很詳細;

我們主要用了以下幾個引數

-L: 埠轉發

-C: 壓縮傳送資料

-f: 後臺執行

-N: 不執行遠端命令

常規alias

# 這條命令會在後臺執行
alias mstunnel=ssh -L 3306:localhost:3306  [email protected] -NCf

# 若是遠端轉遠端 用-R 替換-L
複製程式碼

傳遞引數的alias

shellalias不支援引數的傳遞,要傳遞只能寫成function再賦值到alias

可以設定多個佔位符,依次遞增(比如埠,域名都變成外部傳入什麼的,看自己喜好了)


# ssh tunnel
function sst(){
  ssh -L 3306:localhost:3306  [email protected]$1 -NCf
}
alias sst=sst

複製程式碼

關閉會話(ssh tunnel)

分步進行的依賴lsof,kill

  • 找到對應的程序PID ,lsof -i tcp:22(查詢誰用著22的埠,ssh tunnel預設走tcp)
  • kill -9 pid , -9 是終止程序

若是要一步到位的,就要藉助幾個命令一起了,awk,xargs以及管道(|)

# 意思就是
# 查詢TCP且埠22的程序
# 輸出第二行的第二列(第一行是列名)
# stdin 轉為arguments  給kill 
lsof -i tcp:22 | awk 'NR==2 { print $2}' |xargs   kill -9

# 當然也可以當做一個表示式來寫
kill -9 $(lsof -i tcp:22 | awk 'NR==2 { print $2}')


# 若是要同時關閉多個引用該埠的程序 , NR!=1 即可 , kill 支援殺多程序
# 有傳遞引數的alias記得用function 來實現!!!


複製程式碼

若是ssh沒有配置定時傳送訊號,一段時間後會自動停止會話(packet_write_wait:);

此時要麼去配置,要麼我們改寫下alias , 用-o ServerAliveInterval=60 來保持連線的連線這

ssh -o ServerAliveInterval=60 -L  3306:localhost:3306  [email protected] -NCf
複製程式碼

IPV6就帶上 -6

  • npm模組的姿勢

可以通過安裝ssh2,Promise成功後再去連結資料庫;

不考慮用這種,因為實際伺服器都是內部直連的,隧道我們也在開發過程用的比較多


總結

語法轉義

  • 若是使用js檔案

目前的版本,還是要考慮commonjs的寫法,為什麼這樣說,

我把資料庫連結的配置檔案分離出來,不能用export default

匯入的時候也不能用...(rest)解耦的方式. 不然會報語法錯誤

  • ts檔案

可以任性使用ES6+語法

有不對之處請留言,會及時修正,謝謝閱讀