使用go制作微服务数据计算

目的

1 主进程为nodejs 进程,为了给nodejs 进程提供计算心率hrv服务,制作该微服务进程,占用一个端口
2 利用go服务携程进行概率计算服务,不占用nodejs主进程

2 图示结构

2.1步骤如下

a 从传感器传入数据,接收到数据以后存储
b 需要计算的时候调用算法服务

2.2 如下图所示使用go制作微服务数据计算_第1张图片

3 微服务制作

3.1 充分利用go语言携程功能,制作sdnn心率计算包

hrv 5 min RR 间期 平均值标准差 sdann
24h 正常的RR间期总体标准差 sdnn
24h 每5分钟时段 标准差的平均值 sdnn index
两个相邻RR间期 差值的均方根RMSSD
24h 相邻两个正常RR 间期差值 大于50ms 的个数百分比pnn50
主要计算公式如下
使用go制作微服务数据计算_第2张图片

3.2 制作http服务示例

写好mode包模式,go.mode 内容如下
module hrv
go 1.15
require github.com/garyburd/redigo v1.6.3

制作数据结构

如下,心率数据和时间,姓名

type Data struct {
	Heart int
	Time  int
	Name  string
}

type Cmd struct {
	Type int
	Data []Data
}

携程函数示例

func calculate1(cmd *Cmd, w http.ResponseWriter) {
	//in1 := []float32{71, 72, 69, 70, 65, 74}
	size := len(cmd.Data)
	var in []float32 = make([]float32, size)

	for i, v := range cmd.Data {
		in[i] = (float32)(v.Heart)
	}
	//标准差函数在sdnn包里面
	ret := sdnn.Get_Stddev(in)
	fmt.Fprintf(w, "%f", ret)

	//
}

启动函数的时候这样写
go calculate(cmd,w)
这样没接收到一个任务以后,都会启动携程处理,然后返回结果

package main

import (
	"encoding/json"
	"fmt"
	"hrv/sdnn"
	"html"
	"io/ioutil"
	"log"
	"net/http"
)

type Data struct {
	Heart int
	Time  int
	Name  string
}

type Cmd struct {
	Type int
	Data []Data
}

// 创建一个错误处理函数,避免过多的 if err != nil{} 出现
func dropErr(e error) {
	if e != nil {
		panic(e)
	}
}
func calculate1(cmd *Cmd, w http.ResponseWriter) {
	//in1 := []float32{71, 72, 69, 70, 65, 74}
	size := len(cmd.Data)
	var in []float32 = make([]float32, size)

	for i, v := range cmd.Data {
		in[i] = (float32)(v.Heart)
	}
	ret := sdnn.Get_Stddev(in)
	fmt.Fprintf(w, "%f", ret)

	//
}
func main() {
    runtime.GOMAXPROCS(4)
	http.HandleFunc("/hrv", func(w http.ResponseWriter, r *http.Request) {

		fmt.Println(html.EscapeString(r.URL.Path))

		if r.Method == "POST" {
			b, err := ioutil.ReadAll(r.Body)
			if err != nil {
				log.Println("Read failed:", err)
			}
			defer r.Body.Close()

			cmd := &Cmd{}
			err = json.Unmarshal(b, cmd)
			if err != nil {
				log.Println("json format error:", err)
			}
			//携程处理
			go calculate1(cmd, w)
			log.Println("cmd:", string(b))
			log.Println("cmd:", cmd.Data[0])

			//w.ResponseWriter("1")
		} else {

			log.Println("not support")

			w.WriteHeader(405)
			return
		}

	})
	fmt.Println("server lister at 8080")
	log.Fatal(http.ListenAndServe(":8080", nil))

}

为了充分利用多核,我们可以设定并发携程处理器个数
runtime.GOMAXPROCS(4)

测试client

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
)

type Data struct {
	Heart int
	Time  int
	Name  string
}
type Cmd struct {
	Type int
	Data []Data
}

func main() {
	str := `{"Type":1,"Data":[{"Heart":78,"Time":678,"Name":"qianbo"},
	{"Heart":75,"Time":679,"Name":"guanzhi"},
	{"Heart":69,"Time":679,"Name":"guanzhi"},
	{"Heart":72,"Time":679,"Name":"guanzhi"},
	{"Heart":73,"Time":679,"Name":"guanzhi"},
	{"Heart":70,"Time":679,"Name":"guanzhi"}
	]}`

	//var arr [2]Data
	//json.Unmarshal([]byte(str), &s)

	// data := make(map[string]interface{})
	// data["Name"] = "qianbo"
	// data["Heart"] = 67
	// data["Time"] = 778

	// D := make(map[string]interface{})
	// D["Type"] = 1
	// D["Data"] = data
	// bytesData, err := json.Marshal(D)

	// if err != nil {
	// 	fmt.Println(err.Error())
	// 	return
	// }
	// reader := bytes.NewReader(bytesData)
	//request, err := http.NewRequest("POST", url, reader)
	url := "http://127.0.0.1:8080/hrv"
	var jsonStr = []byte(str)
	request, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	request.Header.Set("Content-Type", "application/json;charset=UTF-8")
	client := http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	fmt.Println(string(body))

}

运行服务器
go run main.go

运行客户端测试
go run post.go
返回结果如下:
使用go制作微服务数据计算_第3张图片

你可能感兴趣的:(go,golang,微服务,开发语言)