[golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例

news2024/10/5 17:16:36

一.go-micro框架

  1. 前言

上一节讲解了 GRPC微服务集群+ Consul集群+ grpc-consul-resolver相关的案例,知道了微服务之间通信采用的 通信协议,如何实现 服务的注册和发现,搭建 服务管理集群,以及服务与服务之间的 RPC通信方式,具体的内容包括: protobuf协议consuldocker部署consul集群GRPC框架的使用等具体的实现方案.以上这些具体的方案都是为了解决: 微服务实践过程中具体的某个问题而提出的,实现微服务架构的项目开发,但是,在具体的项目开发过程中,开发者聚焦的是 业务逻辑的开发功能的实现,大量的 环境配置调试搭建等基础性工作会耗费相当一部分的精力,因此有必要将微服务架构中所涉及到的,相关的解决方案做 集中管理和维护,这就需要使用到 Micro来进行处理
  1. go-micro介绍

Go Micro是一个简化分布式开发 的微服务生态系统,该系统为开发分布式应用程序提供了 高效便捷的模块构建主要目的简化分布式系统的开发,它默认实现了 consul作为服务发现(2019年源码修改了默认使用 mdns),通过 http进行通信,通过 protobuf和 json进行编解码,可以方便开发者们非常简单的开发出微服务架构的项目,并且随着业务模块的增加和功能的增加,Go Micro还能够提供管理微服务环境的工具和功能
github地址: https://github.com/asim/go-micro
  1. go-micro的主要功能

  • 身份验证

身份验证作为一等公民内置,身份验证和授权通过为每个服务提供身份和证书来实现安全的零信任网络,这还包括基于规则的访问控制
  • 动态配置

任何地方加载热重载动态配置,config 接口提供了一种从任何来源(如环境变量、文件、etcd) 加载应用程序级别配置的方法,可以合并源,甚至定义回退
  • 数据存储

一个简单的 数据存储接口,用于 读取、写入删除记录,它默认包括对 内存文件CockroachDB 的支持, 状态和持久性成为原型设计之外的核心要求,Micro 希望将其构建到框架中
  • 服务发现

自动服务注册名称解析,服务发现是 微服务开发的核心,当服务 A 需要与服务 B 通话时,它需要该服务的位置,默认发现机制是 多播 DNS (mdns),一个 zeroconf 系统
  • 负载均衡

基于服务发现的 客户端负载均衡,一旦有了任意数量的 服务实例地址,现在需要一种方法来决定 路由到哪个节点,使用 随机散列负载均衡来提供 跨服务的均匀分布,并在出现问题时 重试不同的节点
  • 消息编码

基于 内容类型动态消息编码,客户端和服务器将使用 编解码器内容类型无缝编码和解码 Go 类型,任何种类的消息都可以被编码并从不同的客户端发送,默认情况下,客户端和服务器会处理此问题,这默认包括 protobuf json
  • RPC 客户端/服务器

基于 RPC 的请求/响应,支持 双向流,为同步通信提供了一个抽象,对服务的请求将被 自动解析、负载均衡、拨号和流式传输
  • Async Messaging

PubSub 作为 异步通信事件驱动架构的一等公民内置, 事件通知微服务开发的核心模式,默认消息系统是 HTTP 事件消息代理
  • 事件流

PubSub 非常适合 异步通知,但对于更高级的用例, 事件流是首选,提供 持久存储,从偏移量和确认中消耗,Go Micro 包括对 NATS Jetstream Redis 流的支持
  • 同步

分布式系统通常以 最终一致的方式构建,对 分布式锁定领导(Leader)的支持作为同步接口内置,当使用 最终一致的数据库调度时,请使用 Sync 接口
  • Pluggable Interfaces

Go Micro 为每个分布式系统抽象使用 Go 接口,因此,这些接口是 可插拔的,并 允许 Go Micro 与运行时无关,可以插入任何底层技术
  1. go-micro安装

github地址: https://github.com/asim/go-micro, 如下,点击CLI后,可以查看安装相关命令 :
通过go install github.com/go-micro/cli/cmd/go-micro@latest安装,成功后,通过 go-micro new service helloworld命令就可以搭建微服务的服务端,客户端,搭建后, 系统会自动生成 .proto, .pb.go等远程调用的文件以及方法
安装如下:运行命令 go install github.com/go-micro/cli/cmd/go-micro@latest

命令完成后,在GOPATH的bin目录就可以查看到对应的go-micro.exe执行文件了

然后查看是否安装成功,输入命令 :go-micro
安装成功

二.go-micro的使用

(一).helloworld简单案例讲解

  1. 创建服务端

在servers目录下运行 :go-micro new service helloworld
  1. 下载项目所需依赖

初次使用时,需执行Makefile里面的命令

Makefile内容如下:
GOPATH:=$(shell go env GOPATH)

.PHONY: init
init:
    @go get -u google.golang.org/protobuf/proto
    @go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    @go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest

.PHONY: proto
proto:
    @protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto

.PHONY: update
update:
    @go get -u

.PHONY: tidy
tidy:
    @go mod tidy

.PHONY: build
build:
    @go build -o helloworld *.go

.PHONY: test
test:
    @go test -v ./... -cover

.PHONY: docker
docker:
    @docker build -t helloworld:latest .

windows下依次执行Markfile init里面的命令:

#init里面的命令:引入需要的包
go get -u google.golang.org/protobuf/proto
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest
#proto:执行生成对应的protobuf相关文件
protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto

linux下通过make命令下载对应依赖或者编译项目

make proto update tidy

完成上面命令后的目录如下:

  1. 初始化服务端项目

go mod init helloworld
go mod tidy

如果出现:

F:\www\go-data\src\go_code\micro\grpc_demo\server\helloworld>go mod tidy
go: finding module for package google.golang.org/protobuf/runtime/protoimpl
go: finding module for package go-micro.dev/v4/logger
go: finding module for package go-micro.dev/v4
go: finding module for package go-micro.dev/v4/server
go: finding module for package go-micro.dev/v4/api
go: finding module for package google.golang.org/protobuf/proto
go: finding module for package google.golang.org/protobuf/reflect/protoreflect
go: finding module for package go-micro.dev/v4/client
go: found go-micro.dev/v4 in go-micro.dev/v4 v4.10.2
go: found go-micro.dev/v4/logger in go-micro.dev/v4/logger v1.18.0
go: found go-micro.dev/v4/api in go-micro.dev/v4/api v1.18.0
go: found go-micro.dev/v4/client in go-micro.dev/v4/client v1.18.0
go: found go-micro.dev/v4/server in go-micro.dev/v4/server v1.18.0
go: found google.golang.org/protobuf/proto in google.golang.org/protobuf v1.30.0
go: found google.golang.org/protobuf/reflect/protoreflect in google.golang.org/protobuf v1.30.0
go: found google.golang.org/protobuf/runtime/protoimpl in google.golang.org/protobuf v1.30.0
go: helloworld/proto imports
        go-micro.dev/v4/api: go-micro.dev/v4/api@v1.18.0: parsing go.mod:
        module declares its path as: github.com/micro/go-micro
                but was required as: go-micro.dev/v4/api

说明下载"go-micro.dev/v4"这个包失败了,这时则需运行命令 go get go-micro.dev/v4,如图:

然后再次执行步骤3中的命令即可

  1. 配置服务端consul

(1).启动consul

在配置consul之前,需要启动consul,命令行执行命令 :consul agent -dev,启动consul服务, 也可以使用 consul集群相关操作进行处理

(2).引入consul包

然后在servers/helloworld/main.go下引入consul包:
可以在import引入包后,执行 go mod tidy ,也可以执行 go get github.com/go-micro/plugins/v4/registry/consul 命令引入
 github.com/go-micro/plugins/v4/registry/consul

(3).实例化consul:

consulReg := consul.NewRegistry()

(4).注册consul

srv := micro.NewService(
    micro.Address("192.168.1.132:8080"),  // 选择注册服务器地址,默认为本机,也可以选择consul集群中的client
    micro.Name(service),
    micro.Version(version),
    micro.Registry(consulReg),
)

(5).详细代码

package main

import (
    "helloworld/handler"
    pb "helloworld/proto"
    "go-micro.dev/v4"
    "go-micro.dev/v4/logger"
    "github.com/go-micro/plugins/v4/registry/consul"
)

var (
    service = "helloworld"
    version = "latest"
)

func main() {
    //集成consul
    consulReg := consul.NewRegistry()
    // Create service
    srv := micro.NewService(
        micro.Address("127.0.0.1:8080"),  //指定微服务的ip:  选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的client
        micro.Name(service),
        micro.Version(version),
        //注册consul
        micro.Registry(consulReg),
    )
    srv.Init(
        micro.Name(service),
        micro.Version(version),
    )

    // Register handler
    if err := pb.RegisterHelloworldHandler(srv.Server(), new(handler.Helloworld)); err != nil {
        logger.Fatal(err)
    }
    // Run service
    if err := srv.Run(); err != nil {
        logger.Fatal(err)
    }
}

(6).结果显示

微服务服务端就配置并启动了
  1. 生成客户端

(1).生成客户端目录

在client目录下运行 :go-micro new client helloworld
目录如下: 结构和服务端结构一致,参考服务端结构
注意:在这里生成的客户端文件夹名字是helloworld-client
里面也存在 Makefile文件,操作和上面服务端一致, 下面就要让 客户端连接上微服务服务端

(2).创建客户端proto文件相关

这里可以直接把服务端中的proto文件夹复制到helloworld-client文件夹下,然后可以初始化项目,删除go.mod, 执行初始化命令 :go mod init helloworld-client, go mod tidy
重新初始化helloworld-client: 删除go.mod文件,然后执行: go mod init helloworld-client, go mod tidy

(3).完善helloworld-client/main.go文件

1).修改helloworld/proto包名字
需要把helloworld/proto修改为helloworld-client/proto

然后也要引入consul包

2).引入consul包
然后在client/helloworld-client/main.go下引入consul包:
可以在import引入包后,执行 go mod tidy ,也可以执行 go get github.com/go-micro/plugins/v4/registry/consul 命令引入
 github.com/go-micro/plugins/v4/registry/consul
3).实例化consul:
consulReg := consul.NewRegistry()
4).注册consul
//集成consul
consulReg := consul.NewRegistry(
    //指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client
    registry.Addrs("127.0.0.1:8500"),
)
// Create service
srv := micro.NewService(
    //注册consul
    micro.Registry(consulReg),
)
5).详细代码
package main

import (
    "context"
    "time"
    pb "helloworld-client/proto"
    "go-micro.dev/v4"
    "go-micro.dev/v4/logger"   
    "go-micro.dev/v4/registry"
    "github.com/go-micro/plugins/v4/registry/consul"
)

var (
    service = "helloworld" //需要和微服务服务端对应的service名统一,这样才能调用该微服务
    version = "latest"
)

func main() {
    //集成consul
    consulReg := consul.NewRegistry(
        //指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client
        registry.Addrs("127.0.0.1:8500"),
    )
    // Create service
    srv := micro.NewService(
        //注册consul
        micro.Registry(consulReg),
    )
    srv.Init()

    // 创建客户端实例
    c := pb.NewHelloworldService(service, srv.Client())
    for {
        // Call service: CallRequest就是.proto中的
        rsp, err := c.Call(context.Background(), &pb.CallRequest{Name: "张三"})
        if err != nil {
            logger.Fatal(err)
        }

        logger.Info(rsp)
        //每隔一段时间请求
        time.Sleep(2 * time.Second)  // 每隔2秒请求
    }
}
6).结果显示
客户端配置操作完成

(二).goodsinfo微服务案例讲解

  1. 创建服务端

在servers目录下运行 :go-micro new service goodsinfo

目录和上面helloworld案例类似,只不过是名字变成了goodsinfo而已

然后修改goodsinfo.proto,增加需要的服务方法:这里的写法和[golang 微服务] 4. gRPC介绍,Protobuf结合gRPC 创建微服务 里面的类似:

syntax = "proto3";

package goodsinfo;

option go_package = "./proto;goodsinfo";

//商品相关方法
service Goodsinfo {
    //AddGoods: 定义增加商品的微服务, 这里的写法和gRPC中的写法一致
    rpc AddGoods(AddRequest) returns (AddResponse) {}
}

//和gRPC中的写法一致
message AddRequest {
    string title = 1;
    string price = 2;
    string content = 3;
}

//和gRPC中的写法一致
message AddResponse {
    string message = 1;
    bool success = 2;
}
  1. 下载项目所需依赖

初次使用时,需执行Makefile里面的命令

Makefile内容如下:
GOPATH:=$(shell go env GOPATH)

.PHONY: init
init:
    @go get -u google.golang.org/protobuf/proto
    @go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    @go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest

.PHONY: proto
proto:
    @protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto

.PHONY: update
update:
    @go get -u

.PHONY: tidy
tidy:
    @go mod tidy

.PHONY: build
build:
    @go build -o helloworld *.go

.PHONY: test
test:
    @go test -v ./... -cover

.PHONY: docker
docker:
    @docker build -t helloworld:latest .

windows下依次执行init里面的命令:

#init:引入相关包
go get -u google.golang.org/protobuf/proto
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest
#proto: 生成protobuf相关文件
protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto

linux下通过make命令下载对应依赖或者编译项目

make proto update tidy

完成上面命令后的目录如下:

生成了goodsinfo相关handler,以及.pb.go文件
  1. 初始化服务端项目

go mod init goodsinfo
go mod tidy

如果出现:

F:\www\go-data\src\go_code\micro\grpc_demo\server\helloworld>go mod tidy
go: finding module for package google.golang.org/protobuf/runtime/protoimpl
go: finding module for package go-micro.dev/v4/logger
go: finding module for package go-micro.dev/v4
go: finding module for package go-micro.dev/v4/server
go: finding module for package go-micro.dev/v4/api
go: finding module for package google.golang.org/protobuf/proto
go: finding module for package google.golang.org/protobuf/reflect/protoreflect
go: finding module for package go-micro.dev/v4/client
go: found go-micro.dev/v4 in go-micro.dev/v4 v4.10.2
go: found go-micro.dev/v4/logger in go-micro.dev/v4/logger v1.18.0
go: found go-micro.dev/v4/api in go-micro.dev/v4/api v1.18.0
go: found go-micro.dev/v4/client in go-micro.dev/v4/client v1.18.0
go: found go-micro.dev/v4/server in go-micro.dev/v4/server v1.18.0
go: found google.golang.org/protobuf/proto in google.golang.org/protobuf v1.30.0
go: found google.golang.org/protobuf/reflect/protoreflect in google.golang.org/protobuf v1.30.0
go: found google.golang.org/protobuf/runtime/protoimpl in google.golang.org/protobuf v1.30.0
go: helloworld/proto imports
        go-micro.dev/v4/api: go-micro.dev/v4/api@v1.18.0: parsing go.mod:
        module declares its path as: github.com/micro/go-micro
                but was required as: go-micro.dev/v4/api

说明下载"go-micro.dev/v4"这个包失败了,这时则需运行命令 go get go-micro.dev/v4,如图:

然后再次执行步骤3中的命令即可

修改远程调用的方法handler/goodsinfo.go

原始的代码:
package handler

import (
    "context"
    "io"
    "time"
    "go-micro.dev/v4/logger"
    pb "goodsinfo/proto"
)

type Goodsinfo struct{}

func (e *Goodsinfo) Call(ctx context.Context, req *pb.CallRequest, rsp *pb.CallResponse) error {
    logger.Infof("Received Goodsinfo.Call request: %v", req)
    rsp.Msg = "Hello " + req.Name
    return nil
}

func (e *Goodsinfo) ClientStream(ctx context.Context, stream pb.Goodsinfo_ClientStreamStream) error {
    var count int64
    for {
        req, err := stream.Recv()
        if err == io.EOF {
            logger.Infof("Got %v pings total", count)
            return stream.SendMsg(&pb.ClientStreamResponse{Count: count})
        }
        if err != nil {
            return err
        }
        logger.Infof("Got ping %v", req.Stroke)
        count++
    }
}

func (e *Goodsinfo) ServerStream(ctx context.Context, req *pb.ServerStreamRequest, stream pb.Goodsinfo_ServerStreamStream) error {
    logger.Infof("Received Goodsinfo.ServerStream request: %v", req)
    for i := 0; i < int(req.Count); i++ {
        logger.Infof("Sending %d", i)
        if err := stream.Send(&pb.ServerStreamResponse{
            Count: int64(i),
        }); err != nil {
            return err
        }
        time.Sleep(time.Millisecond * 250)
    }
    return nil
}

func (e *Goodsinfo) BidiStream(ctx context.Context, stream pb.Goodsinfo_BidiStreamStream) error {
    for {
        req, err := stream.Recv()
        if err == io.EOF {
            return nil
        }
        if err != nil {
            return err
        }
        logger.Infof("Got ping %v", req.Stroke)
        if err := stream.Send(&pb.BidiStreamResponse{Stroke: req.Stroke}); err != nil {
            return err
        }
    }
}
修改成我们想要的代码:
package handler

import (
    "context"
    "go-micro.dev/v4/logger"
    pb "goodsinfo/proto"
)

type Goodsinfo struct{}

func (e *Goodsinfo) AddGoods(ctx context.Context, req *pb.AddRequest, rsp *pb.AddResponse) error {
    logger.Infof("request: %v", req)
    //书写返回的逻辑结果
    rsp.Message = "增加成功"
    rsp.Success = true
    return nil
}
  1. 配置服务端consul

(1).启动consul

在配置consul之前,需要启动consul,命令行执行命令 :consul agent -dev,启动consul服务, 也可以使用 consul集群相关操作进行处理

(2).引入consul包

然后在servers/goodsinfo/main.go下引入consul包:
可以在import引入包后,执行 go mod tidy ,也可以执行 go get github.com/go-micro/plugins/v4/registry/consul 命令引入
 github.com/go-micro/plugins/v4/registry/consul

(3).实例化consul:

consulReg := consul.NewRegistry()

(4).注册consul

srv := micro.NewService(
    micro.Address("192.168.1.132:8080"),  // 选择注册服务器地址,默认为本机,也可以选择consul集群中的client
    micro.Name(service),
    micro.Version(version),
    micro.Registry(consulReg),
)

(5).详细代码

package main

import (

    "goodsinfo/handler"
    pb "goodsinfo/proto"
    "go-micro.dev/v4"
    "go-micro.dev/v4/logger"
    "github.com/go-micro/plugins/v4/registry/consul"
)

var (
    service = "goodsinfo"
    version = "latest"
)

func main() {
    //集成consul
    consulReg := consul.NewRegistry()
    // Create service
    srv := micro.NewService(
        micro.Address("127.0.0.1:8080"),  //指定微服务的ip:  选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的client
        micro.Name(service),
        micro.Version(version),
        //注册consul
        micro.Registry(consulReg),
    )
    srv.Init(
        micro.Name(service),
        micro.Version(version),
    )

    // Register handler
    if err := pb.RegisterGoodsinfoHandler(srv.Server(), new(handler.Goodsinfo)); err != nil {
        logger.Fatal(err)
    }
    // Run service
    if err := srv.Run(); err != nil {
        logger.Fatal(err)
    }
}

(6).结果显示

展示和上面helloworld类似,微服务服务端就配置并启动了
  1. 生成客户端

(1).生成客户端目录

在client目录下运行 :go-micro new client goodsinfo
目录如下: 结构和服务端结构一致,参考服务端结构
里面也存在 Makefile文件,操作和上面服务端一致, 下面就要让 客户端连接上微服务服务端

(2).创建客户端proto文件相关

这里可以直接把服务端中的proto文件夹复制到goodsinfo-client文件夹下,然后可以初始化项目,删除go.mod, 执行初始化命令 :go mod init goodsinfo-client, go mod tidy

如果出现:

go: goodsinfo-client/proto imports
        go-micro.dev/v4/api: go-micro.dev/v4/api@v1.18.0: parsing go.mod:
        module declares its path as: github.com/micro/go-micro
                but was required as: go-micro.dev/v4/api

go get go-micro.dev/v4,和上面服务器解决方案一致

当然,也可以再次执行Makefile中的命令,和上面服务器一致

(3).完善goodsinfo-client/main.go文件

1).修改goodsinfo/proto包名字
需要把goodsinfo/proto修改为goodsinfo-client/proto

然后也要引入consul包

2).引入consul包
然后在client/goodsinfo-client/main.go下引入consul包:
可以在import引入包后,执行 go mod tidy ,也可以执行 go get github.com/go-micro/plugins/v4/registry/consul 命令引入
 github.com/go-micro/plugins/v4/registry/consul
3).实例化consul:
consulReg := consul.NewRegistry()
4).注册consul
//集成consul
consulReg := consul.NewRegistry(
    //指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client
    registry.Addrs("127.0.0.1:8500"),
    )
// Create service
srv := micro.NewService(
    //注册consul
    micro.Registry(consulReg),
)
5).详细代码
package main

import (
    "context"
    "go-micro.dev/v4/registry"
    "time"
    pb "goodsinfo-client/proto"
    "go-micro.dev/v4"
    "go-micro.dev/v4/logger"
    "github.com/go-micro/plugins/v4/registry/consul"
)

var (
    service = "goodsinfo"
    version = "latest"
)

func main() {
    //集成consul
    consulReg := consul.NewRegistry(
        //指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client
        registry.Addrs("127.0.0.1:8500"),
        )
    // Create service
    srv := micro.NewService(
        //注册consul
        micro.Registry(consulReg),
    )

    srv.Init()

    // 创建客户端服务
    c := pb.NewGoodsinfoService(service, srv.Client())

    // Call service
    rsp, err := c.AddGoods(context.Background(), &pb.AddRequest{
        Title: "我是一个商品",
        Price: "20.22",
        Content: "内容展示",
    })
    if err != nil {
        logger.Fatal(err)
    }

    logger.Info(rsp)
}
6).结果显示
客户端配置操作完成

[上一节][golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/666368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot 如何使用 IOC 容器

SpringBoot 如何使用 IOC 容器 Spring 是一个非常流行的 Java 开发框架&#xff0c;它提供了一个强大的 IoC&#xff08;Inversion of Control&#xff09;容器来管理 Java 对象之间的依赖关系。在 SpringBoot 中&#xff0c;我们可以非常方便地使用这个 IoC 容器来管理我们的…

骨传导耳机音质怎么样,几款解析力度不错的骨传导耳机分享

​骨传导耳机在之前的时候一直是“冷门”的&#xff0c;但是随着技术的进步&#xff0c;现在骨传导耳机也逐渐被大家所熟知。对于喜欢运动和健身的人来说&#xff0c;骨传导耳机可以避免佩戴普通耳机导致耳朵疼痛的情况。因此&#xff0c;目前在市面上很多骨传导耳机都很受欢迎…

Git教程(快速上手,超详细)

文章目录 版本控制Git环境配置Git基本理论Git项目搭建Git文件操作使用码云IDEA集成GitGit分支 版本控制 版本迭代:每次更新就会有新的版本&#xff0c;旧的版本需要保留。所以我们需要一个版本控制工具帮助我们处理这个问题 版本控制&#xff08;Revision control&#xff09;是…

入门学习编码器与自编码器1----包括详细的理论讲解与详细的python程序代码,小白直接看懂!!!纯干货

文章目录 前言--为什么要学习编码器和自编码器&#xff1f;一、编码器与自编码器究竟是什么&#xff1f;二、下面是一个简单的Python实现自编码器的示例三、程序运行结果四、查看模型结构总结 前言–为什么要学习编码器和自编码器&#xff1f; 学习编码器和自编码器可以帮助我…

【数据分享】1929-2022年全球站点的逐月平均风速数据(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 对于具体到监测站点的气象数据&#xff0c;之前我们分享过1929-2022年全球气象…

「你将购买的是虚拟内容服务,购买后不支持退订」,真的合理么?

编辑导语&#xff1a;你是否也有见过相似提示&#xff0c;即虚拟内容服务购买之后不予退款&#xff1f;那么你有想过&#xff0c;在这一规定背后&#xff0c;其制约因素都有什么吗&#xff1f;这一规定是合理的吗&#xff1f;用户若真的有退款需求&#xff0c;产品上是否能实现…

卷积计算加速方法--分块卷积1

文章目录 1、大尺寸卷积存在的问题2、分块卷积overlap产生的来源3、分块卷积overlap的计算4、结论及加速效果 1、大尺寸卷积存在的问题 当卷积的输入太大导致内存不够用时&#xff0c;考虑将一大块卷积分成多个小块分别进行卷积&#xff0c;相当于将原始输入分成几个小的输入经…

【C++】C++11:线程库和包装器

C11最后一篇文章 文章目录 前言一、线程库二、包装器和绑定总结 前言 上一篇文章中我们详细讲解了lambda表达式的使用&#xff0c;我们今天所用的线程相关的知识会大量的用到lambda表达式&#xff0c;所以对lambda表达式还模糊不清的可以先将上一篇文章看明白。 一、线程库 在…

域名解析详解

域名解析 记录类型&#xff1a; 提示&#xff1a; 将域名指向云服务器&#xff0c;选择 A&#xff1b; 将域名指向另一个域名&#xff0c;选择 CNAME&#xff1b; 建立邮箱选择 MX&#xff0c;根据邮箱服务商提供的 MX 记录填写。 记录类型解释A用来指定域名的 IPv4 地址&…

燃气管网监测设备:燃气管网压力在线监测

燃气作为一种重要的能源&#xff0c;广泛用于家庭、工业和商业领域。然而&#xff0c;燃气管网系统在运输和分配过程中可能面临压力波动、管道老化、外部破坏等问题&#xff0c;可能导致燃气泄漏和事故发生。燃气管网压力在线监测是保障燃气管网安全运营的重要手段之一。通过燃…

Linux系统之部署Homepage个人导航页

Linux系统之部署Homepage个人导航页 一、Homepage介绍1.1 Homepage简介1.2 Homepage主要特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本3.3 检查系统是否安装Node.js 四、部署Node.js 环境4.1 下载Node…

感谢ChatGPT,救了我狗的命!

前一段时间&#xff0c;国外一位小哥哥在推特上发布了一条消息&#xff0c;声称GPT-4拯救了自家狗狗的性命。 这是怎么一回事呢&#xff1f; 这个小哥哥养了一只两岁的边境牧羊犬&#xff0c;这只牧羊犬被诊断出患有蜱传疾病&#xff0c;这属于一种细菌性传染病。 虽然小哥哥一…

30分钟吃掉DQN算法

表格型方法存储的状态数量有限&#xff0c;当面对围棋或机器人控制这类有数不清的状态的环境时&#xff0c;表格型方法在存储和查找效率上都受局限&#xff0c;DQN的提出解决了这一局限&#xff0c;使用神经网络来近似替代Q表格。 本质上DQN还是一个Q-learning算法&#xff0c;…

金九银十预备秋招: 大厂面试必考点及 Java 面试框架知识点整理

Java 面试 “金九银十”这个字眼对于程序员应该是再熟悉不过的了&#xff0c;每年的金九银十都会有很多程序员找工作、跳槽等一系列的安排。说实话&#xff0c;面试中 7 分靠能力&#xff0c;3 分靠技能&#xff1b;在刚开始的时候介绍项目都是技能中的重中之重&#xff0c;它…

龙膜公益“聚光行动”再起航 为云南山区小学援建绿色电脑教室

中国&#xff0c;上海——近日&#xff0c;全球汽车膜品牌龙膜的公益活动“为山区学校援建绿色电脑教室”在云南泸西县再度起航。为当地的“阿盈里小学”和“歹鲁小学”添置了2间电脑教室&#xff0c;配备了82台再生电脑&#xff0c;为600多名学生提供了数字化设备的使用机会&a…

Android Hilt:强大的依赖注入框架,高级传参解个耦?

作者&#xff1a;J船长 一、Hilt 干依赖注入的 Hilt是干嘛的 Hilt&#xff0c;一个依赖注入框架&#xff0c;谷歌搞出来的&#xff0c;基于Dagger&#xff0c;但是更加简洁易用。 什么是依赖注入 &#xff08;Dependency Injection&#xff09; 依赖注入是一种设计模式。主…

高校劳动积分小程序/基于微信小程序的高校劳动积分系统

摘 要 随着信息技术互联网和小程序的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的微信小程序应运而生&#xff0c;各行各业相继进入信息管理…

系统架构设计师-系统工程与信息系统基础(1)

一、系统工程概念 【系统工程】是一种组织管理技术。 【系统工程】是为了更好的实现系统的目的&#xff0c;对系统的组成要素、组成结构、信息流、控制机构进行分析研究的科学方法。 【系统工程】从整体出发、从系统观念出发、以求【整体最优】 【系统工程】利用计算机作为…

开放式耳机会不会吵到别人?2023年开放式耳机科普!

在了解开放式耳机会不会吵到别人之前&#xff0c;我们先了解下开放式耳机的基本知识&#xff01; 开放式耳机是一种不入耳&#xff0c;没有封闭耳朵的蓝牙耳机&#xff0c;可以听歌的同时接收来自外界声音&#xff0c;安全性高&#xff0c;也减少长期佩戴耳机带来的负担&#…

2023火爆的11门编程语言

2023火爆的11门编程语言 对于我个人来说没有语言偏好&#xff0c;根据不同的应用领域和需求&#xff0c;不同的编程语言都有其独特的优势和适用性。无论使用何种语言只要能更好的实现需求&#xff0c;解决痛点问题&#xff0c;就是好语言。 那么各种语言应用的场景解决了哪些…