菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
0
0

Nodejs创建简单的微服务

原创
05/13 14:22
阅读数 174

微服务是将一个单体服务拆分成一个个服务,而这一个个小服务可以独立部署,并且可以用多种语言构建一个个小服务,且各个服务之间可以统一。微服务之间可以独立地缩放,已达到最高的性能。

微服务之间的通信一般有两种方式:

RPCHTTP
Resutful

RPC 是远程过程调用服务,它提供了一套机制,使得多个语言也能调用其代码,符合Server/Client的风格方式。

Resutful则是使用HTTP的方式构建,来达到通信的目的。

其两者的本质是不同的,一个HTTP ,一个是TCP构建的。

大部分情况下我们使用gRPC的方式进行通信,他是基于HTTP 2.0的传输协议承载了高性能的一种框架,使用起来轻便高效。它使用Proto Buffer为基础作为序列化的格式,这是一种约定俗成。

现在我们创建一个简单的Hello World服务,首先创建Hello.proto

sytanx = "proto3"

package hello;
// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

接着直接创建一个服务,让他读取proto里面的内容。nodejs这边的包主要使用@grpc/grpc-js和@grpc/proto-loader这两个。

安装一下依赖:

npm install @grpc/grpc-js @grpc/proto-loader -D

接着编写load.js文件:

const path = require('path')
const grpc = require('@grpc/grpc-js')
const protoLoader = require('@grpc/proto-loader')

const PROTO_PATH = path.join(__dirname, 'hello.proto')
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
})
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition)

// user package
const { hello} = protoDescriptor

module.exports = {
  hello,
}

载入到proto 文件之后,我们需要实现这个服务的接口,创建名为server.js的文件:

const grpc = require('@grpc/grpc-js')

function sayHello(call, callback) {
  callback(null, {message: 'Hello ' + call.request.name});
}

function main() {
  var server = new grpc.Server();
  server.addService(hello.Greeter.service,
                         {sayHello: sayHello});
  server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
    server.start();
  });
}

把它运行起来,一个简单的微服务就起来了。

node index.js

既然微服务创建起来了,那么怎么样让人知道,他是什么微服务,应该是由哪个端口调用等等…

配置中心

大多情况下我们的服务是未知的,例如服务内连接了数据库,消息队列,以及连接不同的服务。那么怎么让“主”服务知道服务中的位置呢?一般是用分布式的配置中心,将一个个服务配置存储起来,等下次调用的时候直接读取。

那么主服务器发现多个子服务就简单多了。让子服务器主动注册服务到配置中心里,等下次主服务器调用时就知道注册了那些子服务了。

配置中心最常见的是:etcd、consul、nacos。

我们框架的选型是使用consul,主要是因为它包含K/V配对,多数据中心方案,服务的注册与发布,不需要依赖其他的工具。

直接使用docker部署一下consul:

docker run \\
    -d \\
    -p 8500:8500 \\
    -p 8600:8600/udp \\
    --name=badger \\
    consul agent -server -ui -node=server-1 -bootstrap-expect=1 -client=0.0.0.0

接着我们连接配置中心,这样写:

const consul = new Consul({
	host:"0.0.0.0",
	port:8500,
	promisity:true
})

consul.agent.service.register({
	name:"hello",
	address:"0.0.0.0",
	port:50051
})

这样就主动注册到注册中心了。

怎么获取注册中心呢?

直接用API的方式拉取注册中心的一些服务,API 为:

consul.agent.service.list(function (err, data, res) {
    console.log(data);
  });

他返回的值是:

{
  'express-app': {
    ID: 'express-app',
    Service: 'express-app',
    Tags: [],
    Meta: {},
    Port: 3001,
    Address: 'localhost',
    SocketPath: '',
    Weights: { Passing: 1, Warning: 1 },
    EnableTagOverride: false,
    Datacenter: 'dc1'
  }
}

发表评论

0/200
0 点赞
0 评论
收藏