One, foreword

Usually when we do ServerLess, we will think of using Faas services of various clouds, such as Tencent Cloud, AWS, Ali Cloud and so on. But we rarely study how to build a ServerLess service ourselves. This article focuses on how to set up the ServerLess service on the server yourself and how to use it.

What is ServerLess?

Serverless, also known as Serverless. Serverless emphasizes an architectural idea and a service model that lets developers not worry about infrastructure (servers, etc.) but focus on application business logic. Serverless is also the next generation computing engine.

Serverless and FaaS (function as a service) are often considered interchangeable terms, but this is not accurate. Serverless is an architectural pattern with a higher level of abstraction, and ** “FaaS + BaaS” is just an implementation of this architectural pattern **.

Among them, FaaS is a specific type of service, such as AWS Lambda, Google Cloud Functions, Azure Functions, Ali Cloud Function computing and Tencent Cloud Functions, etc. BaaS (Back-end as a Service) can be understood as other types of managed services, such as database services, object storage services, logging services, and so on.

ServerLess has the following characteristics:

  • O&m free: No server hosts or server processes need to be managed.

  • Elastic scaling: Automatic scaling and automatic configuration according to the load. Scale from zero to infinity.

  • Pay-as-you-go: Determine actual costs based on usage.

  • High availability: There is implicit high availability.

Selection of ServerLess technology

There are two solutions, one is based on the existing Faas cloud service, so there is no need to care about building and maintenance, just need to buy (I will not talk about this way, we can go to see Tencent cloud official website documents). The other is to build SeverLess servers. We’re not going to talk about the first way, we’re going to talk about the second way.

There are many open source solutions to build services. The most popular one is OpenFaas library, which is based on Kubernetes service, and the environment is complicated to build. To get started quickly, use a lightweight SeverLess library. Here we choose FnProject. It is easy to start, just need to have docker environment, can run. Rapid deployment can be achieved.

Fnproject is a native container serverless project that supports almost any programming language and can run almost anywhere. Fn is written in the Go language, so it performs well and is very lightweight. Fnproject supports AWS Lambda style (AWS Lambda is a Serverless service provided by Amazon), so you can easily import your Lambda functions and launch them through Fnproject.

Iv. ServerLess basic service construction

First we need to install FnProject, which only supports Linux/Mac. For Windows users, I recommend installing an Ubuntu operating system. With WSL2, it’s relatively simple.

Both the server and client of FnProject are in the same program, so we only need to install an FN-CLI. Now I will talk about the detailed installation steps.

Mac installation examples:

Use Homebrew to install (there is a pit here, we need to change the domestic mirror source, otherwise it will be very slow, Tsinghua mirror)

brew update && brew install fn
Copy the code

Or use the script of FnProject to install

curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
Copy the code

Windows Installation instructions:

First, upgrade your system to support THE WSL2 protocol, install Ubuntu, and then use the script above to install.

Finally, start the ServerLess service

fn start
Port 8080 is used by default
fn start -p 9080 
You can specify a port for startup
Note that if you change the port, you also need to change the environment variable
exportFN_API_URL = http://127.0.0.1:9080Copy the code

5. Generate ServerLess applications

Fnproject provides support for the following five languages, each with corresponding tutorials, here we mainly talk about nodeJS language, other languages you can see by yourself.

  • Go

  • Java

  • Node.js

  • Python

  • Ruby

fn init --runtime node nodeTest Initialize the structure of the Node project
Copy the code

Then let’s look at the directory structure for nodeTest

Understand the func.yaml file

schema_version: 20180708
name: nodetest
version: 0.01.
runtime: node
build_image: fnproject/node:14-dev
run_image: fnproject/node:14
entrypoint: node func.js
Copy the code
  • Schema_version The unique identity of the service, which determines which fields are available

  • Name Indicates the name of the service and directory

  • Version Version of the current function

  • Information about the language in which the Runtime runs

  • Build_image Packaged Docker image

  • Run_image Running Docker image

  • The entrypoint function is started by docker, and this is the last command that docker executes, node fun.js, to start the Node service

Func.js is our code file, which is relatively simple, and prints Hello World, which looks like this

const fdk=require('@fnproject/fdk');

fdk.handle(function(input){
  let name = 'World';
  if (input.name) {
    name = input.name;
  }
  console.log('\nInside Node Hello World function')
  return {'message': 'Hello ' + name}
})
Copy the code

ServerLess deployment

First we need to create app AppName a Node application. The app that manages existing function applications is also equivalent to applying a namespace to your functions. This app name is also used for deployment. Functions in the same app can be deployed together.

# execute fn create app nodeApp in the current directoryCopy the code

Once created, we can deploy our function application. Here fnproject provides us with the deploy command

fn --verbose deploy --app nodeApp --local
Copy the code

Here are some parameters

  • –verbose Prints the details and process of command execution in the console.
  • –app Specifies the app name
  • –local If your ServerLess service needs to be specified here on the local machine, it is not required here on the remote machine

During the execution, fnProject will automatically build the Docker image and install NPM. After the execution, we will see the above results.

Verify and access the function application

How do we access the Severless service? FnProject provides two invocation methods.

The first method is to use the CLI command line

fn invoke nodeApp nodetest  #invoke is a command that fn provides to call funcApp directly
{"message":"Hello World"}  This is the console printout
Copy the code

In the above function example, we found an input argument, so how do we pass the argument to the func app?

Here we can pass it through the shell’s pipe command.

echo -n '{"name":"Felix"}' | fn invoke nodeApp nodetest --content-type application/json
{"message":"Hello Felix"}  This is the console printout
Copy the code

The second is to use the API interface to call.

First, we need to obtain the Api address of the function. To obtain the Api address, run the following command.

fn inspect function nodeApp nodetest
{
        "annotations": {
                "fnproject.io/fn/invokeEndpoint": "http://localhost:8080/invoke/01FG6BBGV9NG8G00GZJ0000002"
        },
        "app_id": "01FG681T38NG8G00GZJ0000001"."created_at": "The 2021-09-22 T08:53:31. 113 z"."id": "01FG6BBGV9NG8G00GZJ0000002"."idle_timeout": 30."image": "Nodetest: hundreds"."memory": 128."name": "nodetest"."timeout": 30."updated_at": "The 2021-09-22 T08:53:31. 113 z"
}
Copy the code

http://localhost:8080/invoke/01FG6BBGV9NG8G00GZJ0000002, this address is our nodetest service request. We can call it Postman, we can call it ajax in our code.

I’m going to use curl to show you. I went one step further, using a POST request to pass data directly to the call interface

curl -X "POST" -H "Content-Type: application/json" -d '{"name":"Felix"}' http://localhost:8080/invoke/01FG6BBGV9NG8G00GZJ0000002
{"message":"Hello Felix"}  This is the console printout
Copy the code

So now that we’ve covered some of the basic capabilities, let’s talk a little bit more advanced applications. For example, how to access the database, customize the DockerFile file, how to debug, etc.

ServerLess advanced demonstration

So first of all, how do I access Mysql? First of all, how do I install Mysql with docker

# Pull mirror firstDocker pull mysql: 5.7# start mysql mirrorDocker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7Copy the code

For Mysql connections, we need to consider configuring db_host separately. Avoid dying in code.

FnProject provides a wealth of environment variables for us to use

  • DB_HOST_URL Specifies the database address link.

  • DB_USER Specifies the database user name.

  • DB_PASSWORD Specifies the database password.

Configure basic database informationFn cf a nodeApp DB_HOST_URL 172.29.149.191You need to specify the host Ip of the container
fn cf a nodeApp DB_HOST_PORT 3306
fn cf a nodeApp DB_NAME db_test
fn cf a nodeApp DB_USER root
fn cf a nodeApp DB_PASSWORD 123456

You can use this command to view environment variables
fn ls cf a nodeApp
Copy the code

Currently an empty database, we need to create a simple database and a table structure

For simplicity, let’s create databases and tables from the command line. For later demonstrations.

 Enter the mysql container
 docker exec -it mysql bash
 # CLI login mysql
 mysql -uroot -p123456
 Create database
 create database db_test;
 use db_test;
 # to create table
CREATE TABLE IF NOT EXISTS `article`(
        `article_id` INT UNSIGNED AUTO_INCREMENT, 
        `article_title` VARCHAR(100) NOT NULL,
        `article_author` VARCHAR(40) NOT NULL,
        PRIMARY KEY ( `article_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
Insert a test data
INSERT INTO article (article_title,article_author) VALUES("Attention is all you need"."Bengio")
Copy the code

Then apply the enablement to our nodeTest function. Install NPM package to connect to mysql.

Traditional mysql joins to concatenate SQL statements, which I’ve always discouraged. I chose an NPM tool that supports SQL Builder.

Here I use a more popular foreign library KNEx (I will not introduce the use of this tool, you learn by yourself)

Now let’s modify the func.js code

const fdk=require('@fnproject/fdk');


fdk.handle(async function(input,ctx){
  let name = 'World';
  if (input.name) {
    name = input.name;
  }
  const knex = require('knex') ({client: 'mysql'.connection: {
      host : ctx.config['DB_HOST_URL'].// Get database configuration environment variables
      port : ctx.config['DB_HOST_PORT'].user : ctx.config['DB_USER'].password : ctx.config['DB_PASSWORD'].database : ctx.config['DB_NAME']}});// Query the table based on the name passed in
  const rows = await knex('article').where('article_title'.'like'.` %${name}% `)
  returnRows}) # redeploy fn --verbose deploy --app nodeApp --local #"POST" -H "Content-Type: application/json" -d '{"name":"you"}' http://localhost:8080/invoke/01FG6BBGV9NG8G00GZJ0000002Get the interface return directly belowJSON
[{"article_id":1."article_title":"Attention is all you need"."article_author":"Bengio"}]
Copy the code

Here we finish accessing the database. We also have access to external services such as Redis and mongodb. There is a problem, however, that we lack connection pooling and need to create a new connection every time, which is not very efficient. But for some small applications, it’s ok to close when you’re done. But there are ways to do this. One is to put the connection outside. Or for this connection operation, and then separate function application, similar to the way of microservitization. I’m not going to go into it here. This is just to give you a step-by-step understanding of how ServerLess works by building your own.

Eight, ServerLess final summary

Here, I simply set up a basic ServerLess service, which needs to be considered more for real production. Service registration discovery, health check, configuration, fault tolerance, monitoring, traffic, access to Kubernetes, etc are all things to consider. However, ServerLess also has some disadvantages. Development and debugging are not very convenient. You need to write your own unit tests and run them locally in advance. Otherwise, it’s the console log. If you do it locally, you also need to pay attention to the details of the business. Too long code is also bad for debugging. For the front end, ServerLess can be used to quickly implement some ideas without relying on the involvement of the server side. It’s still pretty good.