1. 程式人生 > >golang 構建資料服務

golang 構建資料服務

構建資料服務

本部分的目標是使用 golang database/sql 寫出易於閱讀、擴充套件和可維護的資料庫服務。重點是掌握經典的 “entity - dao - service” 層次結構程式設計模型

一、安裝資料庫

golang 推薦的資料庫是 postgresql ,中國程式設計師一般比較喜歡 mysql。

這裡我們僅介紹用 docker 安裝 mysql。

1.1 下載映象

$ sudo docker pull mysql:5.7
$ sudo docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
mysql                 5.7
5709795eeffa 13 days ago 408MB
  • docker pull 從 docker hub 倉庫取名字為 mysql:5.7 映象。 映象名稱格式為 倉庫名:標籤(tag) 預設 tag 是 latest
  • docker images 本地倉庫映象列表

1.2 啟動 mysql 作為主機服務

主機服務(HOST Service)就是作為宿主機器的一個服務程序。

$ sudo docker run -p 3306:3306 --name mysql2 -e MYSQL_ROOT_PASSWORD=root -d
mysql:5.7 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c55170cbf764 mysql:5.7 "docker-entrypoint..." 8 minutes ago Up 8 minutes 0.0.0.0:3306->3306/tcp mysql2

容器可以看作自帶檔案系統和網路環境的程序。

  • docker run 就是執行容器映象檔案系統內部的一個命令(CLI)。
    • 引數 1 是映象 mysql:5.7
    • -p 是容器內部網路埠到主機埠的對映;
    • --name 程序的名稱, ID 是短唯一標識
    • -e 設定程序(容器)的環境變數
    • -d 後臺執行

1.3 啟動 mysql client 訪問伺服器

mysql 映象已自帶了命令列客戶端,啟動 client 的命令:

$ sudo docker run -it --net host mysql:5.7 "sh"
# mysql -h127.0.0.1 -P3306 -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.20 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

這裡:

  • sudo docker run -it --rm --net host mysql:5.7 "sh" 啟動了容器內 sh 程序。
    • -it 等價於 -i -t ,表示使用當前 stdin 和 stdout 作為該程序的 io
    • --rm , 當該程序結束時,自動清理該容器的檔案系統空間
    • --net host,表示容器使用當前主機的網路環境
    • 引數1 引數2,分別是映象和在映象中執行的命令
  • # 表示你處於容器的超級管理員的 shell
  • mysql -h127.0.0.1 -P3306 -uroot -proot mysql 客戶端的命令

1.4 一些問題與注意事項

1、使用 –rm 的重要性

對於 mysql 伺服器,由於沒有使用 –rm 引數,我們建立的資料庫會留在該程序(容器)的檔案系統上。即使該程序停止,也不會清理這些檔案,使用 sudo docker ps -a 可以查到這些容器的檔案系統。

對於 mysql 客戶端工具,由於沒有值得儲存的資料,所以需要程序結束後自動清理。

如果忘記加 --rm 選項,可使用 sudo docker rm $(sudo docker ps -a -q) 可以清理這些殘留的檔案。

2、如果伺服器宕機

如果異常關閉機器,要重啟 mysql ,請使用 sudo docker start ...
更多操作 一張圖讀懂 docker 命令

3、如果忘記使用 -it 選項

這時你無法與應用程式互動,請開啟一個新的控制檯,使用 docker kill 殺死程序

二、mysql 基本資料庫操作

建立資料庫 test : create datebase test; 注意以 ;結束
查詢資料庫: show databases;
設定 test 為當前資料庫: use test;
刪除資料庫 test: drop database test;

顯示錶: show tables;
顯示錶 userinfo 結構: describe userinfo
執行查詢語句: sql statement;

測試:

建立資料庫test,使用者表userinfo,關聯使用者資訊表userdetail。

create database test;
use test;

CREATE TABLE `userinfo` (
    `uid` INT(10) NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(64) NULL DEFAULT NULL,
    `departname` VARCHAR(64) NULL DEFAULT NULL,
    `created` DATE NULL DEFAULT NULL,
    PRIMARY KEY (`uid`)
);

CREATE TABLE `userdetail` (
    `uid` INT(10) NOT NULL DEFAULT '0',
    `intro` TEXT NULL,
    `profile` TEXT NULL,
    PRIMARY KEY (`uid`)
)

三、資料庫訪問

3.1 CRUD 的含義

對於每個資料表(實體 / Entity ),資料操作分為四個大類:

  • Create 建立資料實體
  • Retrieve 獲取資料實體
  • Update 修改資料實體
  • Delete 刪除資料實體

對應的就是四類資料表操作的 sql 語句

3.2 資料驅動管理與資料操作抽象

對於 golang 基礎庫是 database/sql/driver 包完成。它定義了 資料驅動管理 和 資料操作的抽象介面。 如果你熟悉 java java/jdbc ( Java Database Connectivity API) ,golang 對應的就是 “godbc” (jdbc 精簡版)。 主要對應關係如下:

JDBC GoDBC 說明
DriverManager class sql functions makes a connection with a driver
Driver interface driver.Driver interface provides the API for registering and connecting drivers based on JDBC technology (“JDBC drivers”); generally used only by the DriverManager class
Connection interface driver.Conn/Tx interface provides methods for creating statements and managing connections and their properties
Statement interface driver.Stmt interface used to send basic SQL statements
ResultSet interface driver.Result/Rows interface Retrieving and updating the results of a query
mappings for SQL types driver.Value/ValueConverter interface

在驅動層,Conn 以及 Stmt 是不支援併發訪問的有狀態實體,所以需要進一步包裝,以達到簡化應用的目標。

3.3 database/sql 包

database/sql在database/sql/driver提供的介面基礎上定義了一些更高階的方法,用以簡化資料庫操作,同時內部還建議性地實現一個conn pool。

1、載入驅動:

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)
  • _ "github.com/go-sql-driver/mysql" 啟動包在 init() 階段,自動呼叫 database.sql.Register(…) 註冊驅動到應用中。

2、開啟資料庫:

    db, err := sql.Open("mysql", "root:[email protected](127.0.0.1:3306)/test?charset=utf8")
    if err != nil {
        panic(err)
    }

sql.Open()函式用來開啟一個註冊過的資料庫驅動,go-sql-driver中註冊了mysql這個資料庫驅動,第二個引數是DSN(Data Source Name),它是go-sql-driver定義的一些資料庫連結和配置資訊。它支援如下格式:

DNS 格式:

[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

例如:

user@unix(/path/to/socket)/dbname?charset=utf8
user:password@tcp(localhost:5555)/dbname?charset=utf8
user:[email protected]/dbname
user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname

得到的 db 實體的定義是:

type DB struct {
    driver   driver.Driver
    dsn      string
    mu       sync.Mutex // protects freeConn and closed
    freeConn []driver.Conn
    closed   bool
    ...
}

沒有任何匯出屬性,內建連線池,支援多執行緒操作!!!

3、執行 sql 語句

db 有以下方法執行 sql 語句:

    func (db *DB) Exec(query string, args ...interface{}) (Result, error)
    func (db *DB) Prepare(query string) (*Stmt, error)
    func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
    func (db *DB) QueryRow(query string, args ...interface{}) *Row

其中:
* Exec 執行不返回結果行的語句。如 create, update,delete
* Query 返回多行結果
* QueryRow 返回一行結果
* Prepare 返回編譯完成的帶引數模板語句

注意: 這樣的程式碼毫無實戰價值!

四、構建資料服務

為了編寫易於閱讀、擴充套件和維護的程式,讓我們沿著 java jdbc 程式設計風格一路到黑!

程式設計中,我們繼續追尋 “簡單、使用原生庫” 的原則! 同時採用 java 經典的 “entity - dao - service” 層次結構模型:

+---------------+------------------+
| xxx-service   |提供原子交易服務   |     
+---------------+------------------+
| xxx-dao       |提供xxx的資料存取  |   
+---------------+------------------+
| xxx-entity    |定義xxx的實體資料  | 
+---------------+------------------+  

程式碼與檔案結構:: github.com/pmlpml/golang-learning/web/cloudgo-data

4.1 資料庫設定

entities/initial.go

package entities

import (
    "database/sql"

    _ "github.com/go-sql-driver/mysql"
)

var mydb *sql.DB

func init() {
    //https://stackoverflow.com/questions/45040319/unsupported-scan-storing-driver-value-type-uint8-into-type-time-time
    db, err := sql.Open("mysql", "root:[email protected](127.0.0.1:3306)/test?charset=utf8&parseTime=true")
    if err != nil {
        panic(err)
    }
    mydb = db
}

// SQLExecer interface for supporting sql.DB and sql.Tx to do sql statement
type SQLExecer interface {
    Exec(query string, args ...interface{}) (sql.Result, error)
    Prepare(query string) (*sql.Stmt, error)
    Query(query string, args ...interface{}) (*sql.Rows, error)
    QueryRow(query string, args ...interface{}) *sql.Row
}

// DaoSource Data Access Object Source
type DaoSource struct {
    // if DB, each statement execute sql with random conn.
    // if Tx, all statements use the same conn as the Tx's connection
    SQLExecer
}

func checkErr(err error) {
    if err != nil {
        panic(err)
    }
}
  • 在程式包的 init() 函式中載入資料庫驅動
  • SQLExecer interface 和 DaoSource 使得資料存取不需要考慮 transaction,從而使得事務交給服務層決定!
  • checkErr 用於簡化程式處理錯誤

4.2 資料實體定義

定義資料,並完成一些資料約束處理。

entities/userinfo-entity.go

package entities

import (
    "time"
)

// UserInfo .
type UserInfo struct {
    UID        int   `orm:"id,auto-inc"` //語義標籤
    UserName   string
    DepartName string
    CreateAt   *time.Time
}

// NewUserInfo .
func NewUserInfo(u UserInfo) *UserInfo {
    if len(u.UserName) == 0 {
        panic("UserName shold not null!")
    }
    if u.CreateAt == nil {
        t := time.Now()
        u.CreateAt = &t
    }
    return &u
}

4.3 資料訪問 CRUD

entities/userinfo-dao.go

package entities

type userInfoDao DaoSource

var userInfoInsertStmt = "INSERT userinfo SET username=?,departname=?,created=?"

// Save .
func (dao *userInfoDao) Save(u *UserInfo) error {
    stmt, err := dao.Prepare(userInfoInsertStmt)
    checkErr(err)
    defer stmt.Close()

    res, err := stmt.Exec(u.UserName, u.DepartName, u.CreateAt)
    checkErr(err)
    if err != nil {
        return err
    }
    id, err := res.LastInsertId()
    if err != nil {
        return err
    }
    u.UID = int(id)
    return nil
}

var userInfoQueryAll = "SELECT * FROM userinfo"
var userInfoQueryByID = "SELECT * FROM userinfo where uid = ?"

// FindAll .
func (dao *userInfoDao) FindAll() []UserInfo {
    rows, err := dao.Query(userInfoQueryAll)
    checkErr(err)
    defer rows.Close()

    ulist := make([]UserInfo, 0, 0)
    for rows.Next() {
        u := UserInfo{}
        err := rows.Scan(&u.UID, &u.UserName, &u.DepartName, &u.CreateAt)
        checkErr(err)
        ulist = append(ulist, u)
    }
    return ulist
}

// FindByID .
func (dao *userInfoDao) FindByID(id int) *UserInfo {
    stmt, err := dao.Prepare(userInfoQueryByID)
    checkErr(err)
    defer stmt.Close()

    row := stmt.QueryRow(id)
    u := UserInfo{}
    err = row.Scan(&u.UID, &u.UserName, &u.DepartName, &u.CreateAt)
    checkErr(err)

    return &u
}

這裡僅給出儲存資料和查詢資料的程式。要點:

  • 定義了 userInfoDao
    • 建在 DaoSource 基礎上
    • 第一個字母小寫,僅允許包內訪問
  • 在 userInfoDao 基礎上定義了 CRUD 相關方法
  • 每個方法有固定的程式設計風格
    • 首先,定義 SQL 語句
    • 然後,Prepare 語句
    • 執行語句
    • 將輸出結果對映的對應實體或實體列表

這裡最要注意:

  • 的是 sql.Stmt 和 sql.Rows 必須 close(), 務必正確使用 defer 語句!
  • 幾乎每個操作都有 error 要處理啊,寫出健壯的程式是件不容易的事情
  • 你需要確保程式是多執行緒安全的!

4.4 事務與服務

entities/userinfo-service.go

package entities

//UserInfoAtomicService .
type UserInfoAtomicService struct{}

//UserInfoService .
var UserInfoService = UserInfoAtomicService{}

// Save .
func (*UserInfoAtomicService) Save(u *UserInfo) error {
    tx, err := mydb.Begin()
    checkErr(err)

    dao := userInfoDao{tx}
    err = dao.Save(u)

    if err == nil {
        tx.Commit()
    } else {
        tx.Rollback()
    }
    return nil
}

// FindAll .
func (*UserInfoAtomicService) FindAll() []UserInfo {
    dao := userInfoDao{mydb}
    return dao.FindAll()
}

// FindByID .
func (*UserInfoAtomicService) FindByID(id int) *UserInfo {
    dao := userInfoDao{mydb}
    return dao.FindByID(id)
}

建立物件我們使用了事務,查詢沒有使用事務。

4.5 資料服務測試

編寫整合測試指令碼是程式開發最重要的工作。請自己編寫 entities/userinfo_test.go 測試我們編寫的服務!

問題:如何用 travis 測試你的資料服務?

4.6 web 資料服務包裝

首先編寫 HTTP handler 然後加入 HTTP Router 。

service/userinfo-handler.go

package service

import (
    "net/http"
    "strconv"

    "github.com/pmlpml/golang-learning/web/cloudgo-data/entities"

    "github.com/unrolled/render"
)

func postUserInfoHandler(formatter *render.Render) http.HandlerFunc {

    return func(w http.ResponseWriter, req *http.Request) {
        req.ParseForm()
        if len(req.Form["username"][0]) == 0 {
            formatter.JSON(w, http.StatusBadRequest, struct{ ErrorIndo string }{"Bad Input!"})
            return
        }
        u := entities.NewUserInfo(entities.UserInfo{UserName: req.Form["username"][0]})
        u.DepartName = req.Form["departname"][0]
        entities.UserInfoService.Save(u)
        formatter.JSON(w, http.StatusOK, u)
    }
}

func getUserInfoHandler(formatter *render.Render) http.HandlerFunc {

    return func(w http.ResponseWriter, req *http.Request) {
        req.ParseForm()
        if len(req.Form["userid"][0]) != 0 {
            i, _ := strconv.ParseInt(req.Form["userid"][0], 10, 32)

            u := entities.UserInfoService.FindByID(int(i))
            formatter.JSON(w, http.StatusBadRequest, u)
            return
        }
        ulist := entities.UserInfoService.FindAll()
        formatter.JSON(w, http.StatusOK, ulist)
    }
}

service/server.go

package service

import (
    "net/http"

    "github.com/codegangsta/negroni"
    "github.com/gorilla/mux"
    "github.com/unrolled/render"
)

// NewServer configures and returns a Server.
func NewServer() *negroni.Negroni {

    formatter := render.New(render.Options{
        IndentJSON: true,
    })

    n := negroni.Classic()
    mx := mux.NewRouter()

    initRoutes(mx, formatter)

    n.UseHandler(mx)
    return n
}

func initRoutes(mx *mux.Router, formatter *render.Render) {
    mx.HandleFunc("/hello/{id}", testHandler(formatter)).Methods("GET")
    mx.HandleFunc("/service/userinfo", postUserInfoHandler(formatter)).Methods("POST")
    mx.HandleFunc("/service/userinfo", getUserInfoHandler(formatter)).Methods("GET")

}

func testHandler(formatter *render.Render) http.HandlerFunc {

    return func(w http.ResponseWriter, req *http.Request) {
        vars := mux.Vars(req)
        id := vars["id"]
        formatter.JSON(w, http.StatusOK, struct{ Test string }{"Hello " + id})
    }
}

4.7 測試 web 服務

新增資料

首先,用 curl POST 一些資料到網站。

$ curl -d "username=ooo&departname=1" http://localhost:8080/service/userinfo
  • -d 引數是 POST 到伺服器的資料

查詢資料

然後,我們查詢上傳的資料。

$ curl http://localhost:8080/service/userinfo?userid=

4.8 database/sql 庫的問題

使用原生 database/sql 必讀! Go database/sql 教程。即使你認真閱讀了,也不一定能在大併發量下搞定 go sql,直觀感覺用 go sql 程式設計好 辣雞(和 java 比) !

1. 資料庫支援

除了 postgresql 、mysql 、 sqlite3 等開源庫有較好支援外, 不是所有資料庫都有 golang 驅動。有驅動也不一定完美支援 database/sql 庫的標準

2. 資料庫遷移

使用 資料庫 raw sql 語句操作最大問題就是資料庫遷移。好在 golang 僅用於網際網路應用開發,與 Oracle,DB2 等關係不大!

教程 4.4 必須注意,佔位符不一樣

3. Null 處理

golang 是靜態語言, nil 都很少, 處理 null 就痛苦萬分。 建議不用 null。

4. 順序敏感

scan 欄位是有順序的

5. error 處理

我們沒有用 panic/recover 捕獲錯誤。直接使用 database/sql 處理資料,錯誤處理不是容易的工作

五、 使用 ORM(Object Relational Mapping) 庫

在 java 的世界中, jdbc pk orm 是最常見的,目前 ORM 佔上風。 golang 中存在同樣問題!

5.1 golang ORM 常見模組

ORM 工具推薦:

太簡單了,自學!

5.2 是否需要學習 database/sql

和 java 世界一樣,不會 jdbc 只知道 Hibernate 是不會開發資料庫應用的。

5.3 orm or not

這是個複雜的話題,orm 是用的反射技術、犧牲效能獲得易用性。

如果你做面向程式猿的系統應用而不是面向客戶的應用,database/sql 是你的第一選擇;相反,orm 可以讓你獲得開發效率,orm 使得你不需要編寫 dao 服務!

六、進一步工作

  1. 使用 xorm 或 gorm 實現本文的程式,從程式設計效率、程式結構、服務效能等角度對比 database/sql 與 orm 實現的異同!
    • orm 是否就是實現了 dao 的自動化?
    • 使用 ab 測試效能
  2. 參考 Java JdbcTemplate 的設計思想,設計 GoSqlTemplate 的原型, 使得 sql 操作對於愛寫 sql 的程式猿操作資料庫更容易。
    • 輕量級別的擴充套件,程式設計師的最愛
    • 程式猿不怕寫 sql ,怕的是執行緒安全處理和錯誤處理
    • sql 的 CRUD 操作 database/sql 具有強烈的模板特徵,適當的回撥可以讓程式設計師自己編寫 sql 語句和處理 RowMapping
    • 建立在本文 SQLExecer 介面之上做包裝,直觀上是有利的選擇
    • 暫時不用考慮佔位符等資料庫移植問題,方便使用 mysql 或 sqlite3 就可以
    • 參考資源:github.com/jmoiron/sqlx

工作 2 有相當難度!

相關推薦

golang 構建資料服務

構建資料服務 本部分的目標是使用 golang database/sql 寫出易於閱讀、擴充套件和可維護的資料庫服務。重點是掌握經典的 “entity - dao - service” 層次結構程式設計模型 一、安裝資料庫 golang 推薦的資料

golang 構建HTTP服務

   一個go最簡單的Http伺服器程式package main import ( "fmt" "net/http" ) func IndexHandler(w http.ResponseWriter, r *http.Request) { fmt

通過Python利用ADSL伺服器和tinyproxy構建資料自己的動態代理IP池,用django+redis做web服務 (優化版)

代理池初始版:https://blog.csdn.net/MeteorCountry/article/details/82085238 上一篇文章中所搭建的代理池在使用過程中出現了點小問題,代理池中莫名的多出了一些無效代理,檢查日誌後返現是在更新代理 池時舊的代理IP沒有刪除成功,就添加了新

通過Python利用ADSL伺服器和tinyproxy構建資料自己的動態代理IP池,用django+redis做web服務,提供IP介面

應公司業務需求需要在一些地方使用代理,要求連通率高,速度快,最主要的還要便宜,對比多家供應商後,最後還是決定自購撥號服務搭建代理IP池。 需要配置:1.一臺或多臺adsl伺服器(用以提供IP,可網上購買,通過ssh同域名連線)2.一臺正常固定IP伺服器擁來搭建IP代理池。(統一配置:python

Golang 構建網路傳輸資料

網路通訊中,端與端之間只能傳輸二進位制資料流。TCP/IP協議的解析已經完全交給了硬體裝置完成,即便是軟路由等用伺服器上裝軟體來替代硬體裝置也已經相當成熟。我們需要面對的都是應用層的通訊問題。而大部分情況下也無需考慮通訊細節,因為總有各種框架比如長連線的webs

Go實戰--golang中使用Goji微框架(Goji+Mongodb構建服務)

生命不止,繼續 go go go!!! 今天跟大家分享一個web微框架Goji. Goji What is Goji? 枸杞? Goji is a HTTP request multiplexer, similar to net/http.Serv

springboot構建rest服務,打包docker鏡像

eas mod 過程 output key spring odin fig ted 場景 項目提供rest服務,需要導出rest接口文檔,並把服務打包成docker鏡像。 過程 1.使用SpringBoot實現rest服務 Maven的pom.xml <project

用Jersey構建RESTful服務7--Jersey+SQLServer+Hibernate4.3+Spring3.2

sqlserver get user ide ren restful mar ron ddc 一、整體說明 本例執行演示了用 Jersey 構建 RESTful 服務中。怎樣集成 Spring3 二、環境 1.上文的項目RestDemo 2.

Linux常用服務構建-ftp服務

com nload .cn lin ges alt 應用 語言 cat ftp服務器 FTP 是File Transfer Protocol(文件傳輸協議)的英文簡稱,而中文簡稱為“文傳協議”。 用於Internet上的控制文件的雙向傳輸。 同時,它也是一個應用程序(App

深諳賦能之道,美團點評如何構建生活服務終極藍圖?

gin 可視化 團購 一體化 責任 定位 作用 一個 收入 好萊塢大片裏有不少關於終極的定義,例如即將上映的《猩球崛起3:終極之戰》就在預告裏定義了終極的含義:特效驚人和主角凱撒即將大反攻。而在《終結者》系列中,施瓦辛格正是依靠不斷的進化走向機器人的終極,才能守衛和平。

使用spring mvc或者resteasy構建restful服務

很好 trap 如何 系統 路徑 查找 factor 執行 閱讀 看到最近一個項目裏用resteasy來構建restful接口,有點不明白,不少Spring mvc4.0以後也可以很方面的實現restful服務嗎,為啥還要在Spring MVC的項目裏還引入resteasy

Spring-Boot:Spring Cloud構建服務架構

xmlns art 超時 客戶 微服務架構 cover lns created 搭建 概述:   從上一篇博客《Spring-boot:5分鐘整合Dubbo構建分布式服務》 過度到Spring Cloud,我們將開始學習如何使用Spring Cloud 來搭建微服務。繼續采

Chris Richardson微服務翻譯:構建服務之微服務架構的進程通訊

標記 pac blog ural action 客戶端 靈活 dso 不兼容 Chris Richardson 微服務系列翻譯全7篇鏈接: 微服務介紹 構建微服務之使用API網關 構建微服務之微服務架構的進程通訊(本文) 微服務架構中的服務發現 微服務之事件驅動的數據管理

Spring Cloud構建服務架構分布式配置中心

post ast github 構造 clas mas files cli .class 在本文中,我們將學習如何構建一個基於Git存儲的分布式配置中心,並對客戶端進行改造,並讓其能夠從配置中心獲取配置信息並綁定到代碼中的整個過程。 準備配置倉庫 準備一個git倉庫,可

【docker】基於Dockerfile構建mysqld服務鏡像

mysqld服務鏡像一 創建構建目錄結構 # mkdir -pv docker/mysql# cd docker/mysql/二 寫Dockerfile 文件# vim Dockerfile #此處 sshd:latest 為上篇文章中創建的鏡像#此Dockerfile 「dookerpool」的

【docker】基於Dockerfile構建monogdb服務鏡像

monogdb服務鏡像① 查看內容,包括寫好的Dockerfile和若幹腳本等。從GitHub Dockerpool社區賬戶下載Mongodb鏡像項目:git clone https://github.com/DockerPool/Mongodb.git 並修改文件[root@docker1 Mongodb]

dockerfile用源碼包構建tomcat服務

docker dockerfile tomcat 甘兵 一、說明centos基於docker官方鏡像來制作的,用tomcat源碼包生成的鏡像,本環境中tomcat安裝目錄位於:/usr/local/,jdk安裝目錄位於:/usr/,如果你使用dockerfile buid此鏡像,你要提前下載好

SpringBoot構建服務實戰

自動 als star wire 文件內容 date arc dem char 1. 創建一個Maven項目, 目錄結構: pom.xml文件內容如下: <project xmlns="http://maven.apache.org/POM/4.0

mysql 數據庫服務概述 、 構建MySQL服務器 、 數據庫基本管理 、 MySQL數據類型 、

int 添加 now() 生產 枚舉類型 linu homework 記錄 安裝操作系統 08:30------09:0009:00------12:00ftp服務器:172.40.50.117 7000軟件 softpackage/mysql筆記 nsd17

構建服務架構Spring Cloud:服務註冊與發現(Eureka、Consul)

comm 簡介 foundry 架構 eas args 包含 什麽 其他 Spring Cloud簡介 Spring Cloud是一個基於Spring Boot實現的雲應用開發工具,它為基於JVM的雲應用開發中涉及的配置管理、服務發現、斷路器、智能路由、微代理、控制總線、全