简介

MemFire Cloud 提供Python、Java、spring、golang、nodejs、小程序开发示例,讲述如何编译执行程序,帮助用户如何采用多种语言来使用连接MemFire Cloud。

Python示例

示例下载地址
python示例下载地址:https://gitee.com/memfiredb/memfiredb-example-python

环境描述
• python 2.7
• pip install sqlalchemy==1.3.23
• pip install psycopg2-binary

创建示例应用
1、加密连接
• 登录cloud.memfiredb.com创建证书认证数据库test,并下载证书,python程序请选择“常规”类型的证书
• 下载证书时,会下载三个文件,有的浏览器可能会进行拦截,取消拦截即可
• 证书下载后上传的linux服务器之后,要确保memfiredb.key文件的权限是0600,否则程序会抛出异常
• sslmode选择“verify-ca”
(1)编辑代码文件main.py,文件内容如下:

# -*- coding: utf-8 -*-
"""
Copyright (c) 2020, Nimblex Co .,Ltd.

Created on 2020-12-11 11:28
"""
import sys

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import sqlalchemy.engine.url as url


Base = declarative_base()


class Counter(Base):
    __tablename__ = 'counters'

    id = Column(Integer, primary_key=True)
    counter = Column(Integer)


engine = None


def init_db_engine(host, port, dbname, user, passwd, ssl_ca, ssl_cert, ssl_key):
    global engine
    uri = url.URL(
        drivername="postgresql",
        host=host,
        port=port,
        username=user,
        password=passwd,
        database=dbname,
    )

    ssl_args = {
        "sslmode": "verify-ca",
        "sslrootcert": ssl_ca,
        "sslcert": ssl_cert,
        "sslkey": ssl_key
    }
    engine = create_engine(uri, connect_args=ssl_args, encoding='utf-8', echo=False,
                           pool_size=100, pool_recycle=3600, pool_pre_ping=True)


def get_session():
    global engine
    SessionCls = sessionmaker(bind=engine)
    return SessionCls()


def main():
    host = sys.argv[1]
    port = int(sys.argv[2])

    init_db_engine(host, port, 'test', 'test', 'test', './root.crt', './memfiredb.crt', './memfiredb.key')
    Base.metadata.create_all(engine)

    session = get_session()
    session.execute('delete from counters')
    cnt = Counter(counter=1)
    session.add(cnt)
    session.commit()
    session.close()


if __name__ == '__main__':
    main()

(2)执行程序 python main.py

2、非加密连接
• 登录cloud.memfiredb.com创建非证书认证数据库test,点击“连接信息”按钮,获取数据库的连接信息。
(1)编辑代码文件main.py,文件内容如下:


# -*- coding: utf-8 -*-
"""
Copyright (c) 2020, Nimblex Co .,Ltd.

Created on 2020-12-10 15:42
"""
import threading
import sys

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import OperationalError
import sqlalchemy.engine.url as url


Base = declarative_base()


class Counter(Base):
    __tablename__ = 'counters'

    id = Column(Integer, primary_key=True)
    counter = Column(Integer)


engine = None


def init_db_engine(host, port, dbname, user, passwd):
    global engine
    uri = url.URL(
        drivername="postgresql",
        host=host,
        port=port,
        username=user,
        password=passwd,
        database=dbname,
    )
    engine = create_engine(uri, encoding='utf-8', echo=False,
                           pool_size=100, pool_recycle=3600,
                           pool_pre_ping=True)


def get_session():
    global engine
    SessionCls = sessionmaker(bind=engine)
    return SessionCls()


def test_transaction_try_again():
    def incrInTx():
        session = get_session()
        try:
            cnt = session.query(Counter).first()
            cnt.counter = cnt.counter + 1
            session.add(cnt)
            session.commit()
        finally:
            session.rollback()
            session.close()

    def retryer():
        while 1:
            try:
                incrInTx()
            except OperationalError as e:
                message = repr(e)
                if ('Try again' in message or '40001' in message or 'Restart read required' in message):
                    print('try again')
                    continue

                # 其他异常
                raise e

            return

    threads = []
    for x in range(5):
        t = threading.Thread(target=retryer)
        t.start()
        threads.append(t)

    for t in threads:
        t.join()


def main():
    host = sys.argv[1]
    port = int(sys.argv[2])
    dbname = sys.argv[3]
    dbuser = sys.argv[4]
    dbpassword = sys.argv[5]

    init_db_engine(host, port, dbname, dbuser, dbpassword)
    Base.metadata.create_all(engine)

    session = get_session()
    session.execute('delete from counters')
    cnt = Counter(counter=1)
    session.add(cnt)
    session.commit()
    session.close()

    test_transaction_try_again()


if __name__ == '__main__':
    main()

(2)执行程序

python main.py

Java示例

示例下载地址
Java示例下载地址:https://gitee.com/memfiredb/memfiredb-example-java

环境描述
• Java Development Kit (JDK) 1.8, or later
• Apache Maven 3.3 or later

创建示例应用
1、创建POM

 <?xml version="1.0"?>
<project
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>

  <groupId>cn.nimblex.apps</groupId>
  <artifactId>mfsample</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>org.postgresql</groupId>
      <artifactId>postgresql</artifactId>
      <version>42.2.5</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.1</version>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}/lib</outputDirectory>
              <overWriteReleases>true</overWriteReleases>
              <overWriteSnapshots>true</overWriteSnapshots>
              <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

执行如下命令,创建目录
mkdir -p src/main/java/com/memfire/sample/apps

2、加密连接
• 在MemFire Cloud平台上完成注册操作,并创建证书认证的数据库test
• 点击数据库test的连接信息,下载jdbc访问证书,需要包括memfiredb.crt memfiredb.key root.crt,并拷贝到运行java程序的环境下;

(1)编辑源码文件MFSSLSample.java:src/main/java/com/memfire/sample/apps/MFSSLSample.java

package com.memfire.sample.apps;
import java.util.Properties;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


class SSLCandidate extends Thread {   

    private String _name;
    private Connection connection = null;
    public static String _host = "101.132.186.106:5433";
    public static String _dbname = "d0000001ccbdf7df0ba54c6990b881d9cert_test";
    public static String _dbuser = "cert_test";
    public static String _dbpassword = "test_123";
    SSLCandidate(String name) {
        _name = name;
    }


    public void say() {
        //System.out.println(_name + " say: I am president");
        int wait = 0;
        while (true) {
            try {
            if (wait != 0) {
                Thread.sleep(wait);
            }
            wait = 0;
            String insertStmt = "UPDATE president set name='" + _name + 
                                                "' WHERE term=" + 46;
            connection.createStatement().executeUpdate(insertStmt);
            System.out.println(_name + " say: I am president");
            } catch (Exception e) {
                System.err.println("say Error: " + e.getMessage());
                if (e.getMessage().contains("Restart read required") || 
                        e.getMessage().contains("40001") ||
                        e.getMessage().contains("Try again")) {
                    System.err.println("retry soon");
                    wait = 1000;
                    continue;
                }
            }
            break;
        }
    }
    public void run() {
        try {
            String url = "jdbc:postgresql://" + _host + "/" + _dbname;
            Properties properties = new Properties();
            properties.setProperty("user", _dbuser);
            properties.setProperty("password", _dbpassword);
            properties.setProperty("ssl", "true");
            properties.setProperty("sslrootcert", "/root/.memfiredb/root.crt");
            properties.setProperty("sslkey", "/root/.memfiredb/memfiredb.key");
            properties.setProperty("sslcert", "/root/.memfiredb/memfiredb.crt");
            properties.setProperty("sslmode", "verify-ca");

            connection = DriverManager.getConnection(
                 url,properties );


            int i = 0;
            while(i < 1000) {
                say();
                Thread.sleep(1000);
            }

            connection.close();

        } catch (Exception e) {
            System.err.println("run Error: " + e.getMessage());
        }
    }
}  

public class MFSSLSample {
  public static void main(String[] args) {
    try {
      // Create the DB connection
      Class.forName("org.postgresql.Driver");
      Connection connection = null;
      String url = "jdbc:postgresql://" + SSLCandidate._host + "/" + SSLCandidate._dbname;
      Properties properties = new Properties();
      properties.setProperty("user", SSLCandidate._dbuser);
      properties.setProperty("password", SSLCandidate._dbpassword);
      properties.setProperty("ssl", "true");
      properties.setProperty("sslrootcert", "/root/.memfiredb/root.crt");
      properties.setProperty("sslkey", "/root/.memfiredb/memfiredb.key");
      properties.setProperty("sslcert", "/root/.memfiredb/memfiredb.crt");
      properties.setProperty("sslmode", "verify-ca");

      System.out.println("url:" + url );
      connection = DriverManager.getConnection(
                 url,properties);

      // Create table 'president'
      String createStmt = "CREATE TABLE IF NOT EXISTS president (name varchar, " +
                                                 "term int);";
      connection.createStatement().execute(createStmt);

      // Insert a row.
      String insertStmt = "INSERT INTO president (name, term)" +
                                                " VALUES ('Joseph Robinette Biden', 46);";
      connection.createStatement().executeUpdate(insertStmt);

      // Close the client.
      connection.close();
    } catch (Exception e) {
        System.err.println("main Error: " + e.getMessage());
    }

    SSLCandidate p1 = new SSLCandidate("Joseph Robinette Biden");
    SSLCandidate p2 = new SSLCandidate("Robert Trump");
    p1.start();
    p2.start();
  }
}

3、无加密连接
• 在MemFire Cloud平台上完成注册操作,并创建数据库非证书认证pass_test数据库
编辑源码文件MFSample.java:src/main/java/com/memfire/sample/apps/MFSample.java

 package com.memfire.sample.apps;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


class Candidate extends Thread {   

    private String _name;
    private Connection connection = null;
    public static String _host = "101.132.254.29:5433";
    public static String _dbname = "d0000001ccbdf7df0ba54c6990b881d9pass_test";
    public static String _dbuser = "pass_test";
    public static String _dbpassword = "test_123";
    Candidate(String name) {
        _name = name;
    }


    public void say() {
        System.out.println(_name + " say: I am president");
        int wait = 100;
        while (true) {
            try {
            Thread.sleep(wait);
            wait = 100;
            String insertStmt = "UPDATE president set name='" + _name + 
                                                "' WHERE term=" + 46;
            connection.createStatement().executeUpdate(insertStmt);
            } catch (Exception e) {
                System.err.println("Error: " + e.getMessage());
                if (e.getMessage().contains("Restart read required") || 
                        e.getMessage().contains("40001") ||
                        e.getMessage().contains("Try again")) {
                    System.err.println("retry soon");
                    wait = 1000;
                    continue;
                }
            }
            break;
        }
    }
    public void run() {
        try {
            connection = DriverManager.getConnection(
                 "jdbc:postgresql://"+ _host + "/" + _dbname ,_dbuser, _dbpassword);


            int i = 0;
            while(i < 1000) {
                say();
                Thread.sleep(100);
            }

            connection.close();

        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}  

public class MFSample {
  public static void main(String[] args) {
    try {
      // Create the DB connection
      Class.forName("org.postgresql.Driver");
      Connection connection = null;
      connection = DriverManager.getConnection(
                 "jdbc:postgresql://"+ Candidate._host + "/" + Candidate._dbname ,Candidate._dbuser, Candidate._dbpassword);

      // Create table 'president'
      String createStmt = "CREATE TABLE IF NOT EXISTS president (name varchar, " +
                                                 "term int);";
      connection.createStatement().execute(createStmt);

      // Insert a row.
      String insertStmt = "INSERT INTO president (name, term)" +
                                                " VALUES ('Joseph Robinette Biden', 46);";
      connection.createStatement().executeUpdate(insertStmt);

      // Close the client.
      connection.close();
    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }

    Candidate p1 = new Candidate("Joseph Robinette Biden");
    Candidate p2 = new Candidate("Robert Trump");
    p1.start();
    p2.start();
  }
}

4、编译操作
mvn package

5、执行
加密连接执行操作:
java -cp postgresql-42.2.18.jar:target/mfsample-1.0.jar com.memfire.sample.apps.MFSSLSample

无加密连接执行操作:
java -cp postgresql-42.2.18.jar:target/mfsample-1.0.jar com.memfire.sample.apps.MFSample

Golang示例

示例下载地址
Golang示例下载地址:https://gitee.com/memfiredb/memfiredb-example-golang

环境描述
• Go version 1.8 , or later
• Go PostgreSQL driver 已经安装
go get github.com/lib/pq

创建示例应用
1、加密连接
• 在MemFire Cloud平台上完成注册操作,并创建证书认证的数据库test
• 点击数据库test的连接信息,下载访问证书,需要包括memfiredb.crt memfiredb.key root.crt,并拷贝到运行go程序的环境下;
创建源码文件main.go,文件内容如下:

/**
Copyright (c) 2020, Nimblex Co .,Ltd.
Created on 2020-07-21 19:35
**/
package main

import (
    "database/sql"
    _ "github.com/lib/pq"
    "log"
)

func main() {
    db, err := sql.Open("postgres", "user=test password=test dbname=test host=192.168.80.161 port=5433 sslmode=require sslcert=./memfiredb.crt sslkey=./memfiredb.key sslrootcert=./ca.crt")
    if err != nil {
        log.Fatal("数据库连接失败" + err.Error())
    }

    defer db.Close()
    rows, err := db.Query("SELECT * FROM table_name WHERE id = 1")
    if err != nil {
        log.Fatal(err.Error())
    }
    println(rows)
}

2、无加密连接
• 在MemFire Cloud平台上完成注册操作,并创建数据库非证书认证dbname数据库
创建源码文件main.go,文件内容如下:

  **
Copyright (c) 2020, Nimblex Co .,Ltd.
Created on 2020-12-10 11:59
**/

package main

import (
    "context"
    "flag"
    "fmt"
    "github.com/go-pg/pg/v10"
    "github.com/go-pg/pg/v10/orm"
    "strings"
    "sync"
)

var (
    addr   = flag.String("addr", "192.168.80.161:5433", "memfire address to connect")
    user   = flag.String("user", "test", "memfire user")
    passwd = flag.String("passwd", "test", "memfire password")
    dbname = flag.String("db", "dbname", "memfire database name to connect")
)

func panicIf(err error) {
    if err != nil {
        panic(err)
    }
}

func test_transaction_try_again(db *pg.DB) {
    incrInTx := func(db *pg.DB) error {
        // Transaction is automatically rolled back on error.
        return db.RunInTransaction(db.Context(), func(tx *pg.Tx) error {
            var counter int
            _, err := tx.QueryOne(
                pg.Scan(&counter), `SELECT counter FROM counters FOR UPDATE`)
            if err != nil {
                return err
            }

            counter++

            _, err = tx.Exec(`UPDATE counters SET counter = ?`, counter)
            return err
        })
    }

    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for {
                err := incrInTx(db)
                if err != nil {
                    if strings.Contains(err.Error(), "40001") ||
                        strings.Contains(err.Error(), "Try again") ||
                        strings.Contains(err.Error(), "Restart read required") {
                        fmt.Println("Try again")
                        continue
                    }
                    panic(err)
                }
                break
            }

        }()
    }
    wg.Wait()
}

type Counter struct {
    Counter int64
}

type User struct {
    Id     int64
    Name   string
    Emails []string
}

// createSchema creates database schema for Counter/ User
func createSchema(db *pg.DB) error {
    models := []interface{}{
        (*Counter)(nil),
        (*User)(nil),
    }

    for _, model := range models {
        err := db.Model(model).CreateTable(&orm.CreateTableOptions{
            Temp:        false,
            IfNotExists: true,
        })
        if err != nil {
            return err
        }
    }
    return nil
}

func main() {
    flag.Parse()

    opt := pg.Options{
        Addr:     *addr,
        User:     *user,
        Password: *passwd,
        Database: *dbname,
        OnConnect: func(ctx context.Context, cn *pg.Conn) error {
            println("new connection created")
            return nil
        },
    }

    db := pg.Connect(&opt)
    defer db.Close()

    err := createSchema(db)
    panicIf(err)

    _, err = db.Exec("delete from counters")
    panicIf(err)

    cnt := &Counter{
        Counter: 1,
    }
    _, err = db.Model(cnt).Insert()
    panicIf(err)

    test_transaction_try_again(db)

3、编译执行
go run main.go

Spring示例

示例下载地址 Spring示例下载地址:https://gitee.com/memfiredb/mefiredb-example-spring

下载证书【可选-如果创建数据库时未勾选证书认证则不需要】
登录cloud.memfiredb.com 创建数据库并下载证书,证书类型选择“jdbc” 将下载的证书保存到合适的路径,本示例例中保存到/home/.memfiredb/中 查看数据库信息,包括服务器地址、数据库名、用户名、密码

修改配置文件中datasource【如果创建数据库时未勾选证书认证则url中不需要配置ssl相关内容】
src/main/resources/application.properties

# Data-source config.
# 请修改服务器地址、数据库名、用户名、密码
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://192.168.80.5:5433/d0000005e2e1ead563d7e1b07a9a444cspring?ssl=true&sslmode=verify-ca&sslcert=/home/.memfiredb/memfiredb.crt&sslkey=/home/.memfiredb/memfiredb.key&sslrootcert=/home/.memfiredb/root.crt
spring.datasource.username=spring
spring.datasource.password=spring_123

编译

$ mvn -DskipTests package

运行

$ mvn spring-boot:run

results matching ""

    No results matching ""