(15)go-micro微服务main.go开发

目录
  • 一 导包
  • 二 配置中心
  • 三 注册中心
  • 四 zap日志初始化
  • 五 初始化Mysql数据库
  • 六 初始化Redis连接
  • 七 注册服务
  • 八 初始化服务
  • 九 注册 handle
  • 十 启动服务
  • 十一 main.go全部代码
  • 十二 最后

一 导包

import (
   micro2 "account/common/micro"
   "account/config/logger"
   "account/config/mysql"
   "account/config/redis"
   "account/domain/repository"
   "account/domain/service"
   "account/handler"
   "account/proto/account"
   "fmt"
   _ "github.com/jinzhu/gorm/dialects/mysql"
   "github.com/micro/go-micro/v2"
   "github.com/micro/go-micro/v2/registry"
   "github.com/micro/go-plugins/registry/consul/v2"
   "go.uber.org/zap"
)

二 配置中心

// 1.配置中心
consulConfig, err := micro2.GetConsulConfig("localhost", 8500, "/micro/config")
if err != nil {
   fmt.Printf("Init consulConfig failed, err: %v\n", err)
}

三 注册中心

// 2.注册中心
consulRegistry := consul.NewRegistry(func(options *registry.Options) {
   options.Addrs = []string{
      "127.0.0.1:8500",
   }
})
if err := micro2.GetAccountFromConsul(consulConfig, "account"); err != nil {
   fmt.Printf("Init consul failed, err: %v\n", err)
}
fmt.Println(micro2.ConsulInfo)

四 zap日志初始化

// 3.zap日志初始化
if err := logger.Init(); err != nil {
   fmt.Printf("Init logger failed, err: %v\n", err)
   return
}
defer zap.L().Sync()

五 初始化Mysql数据库

// 5.初始化数据库
db, err := mysql.MysqlInit(micro2.ConsulInfo.Mysql.User, micro2.ConsulInfo.Mysql.Pwd, micro2.ConsulInfo.Mysql.Database)
if err != nil {
   logger.Error(err)
   return
}
defer db.Close()
// 创建实例
accountService := service.NewUserService(repository.NewUserRepository(db))

六 初始化Redis连接

// 6.初始化Redis连接
if err := redis.Init(); err != nil {
   logger.Error(err)
   return
}
defer redis.Close()

七 注册服务

// 8.注册服务
registryService := micro.NewService(
   micro.Name(micro2.ConsulInfo.Micro.Name),
   micro.Version(micro2.ConsulInfo.Micro.Version),
   //暴露的服务地址
   micro.Address(micro2.ConsulInfo.Micro.Address),
   //添加consul 注册中心
   micro.Registry(consulRegistry),
)

八 初始化服务

// 9.初始化服务
registryService.Init()

九 注册 handle

// 10.注册Handle
account.RegisterAccountHandler(registryService.Server(), &handler.Account{AccountService: accountService})

十 启动服务

// 11.启动服务
if err := registryService.Run(); err != nil {
   logger.Fatal(err)
}

十一 main.go全部代码

package main

import (
   micro2 "account/common/micro"
   "account/config/logger"
   "account/config/mysql"
   "account/config/redis"
   "account/domain/repository"
   "account/domain/service"
   "account/handler"
   "account/proto/account"
   "fmt"
   _ "github.com/jinzhu/gorm/dialects/mysql"
   "github.com/micro/go-micro/v2"
   "github.com/micro/go-micro/v2/registry"
   "github.com/micro/go-plugins/registry/consul/v2"
   "go.uber.org/zap"
)

func main() {
   // 1.配置中心
   consulConfig, err := micro2.GetConsulConfig("localhost", 8500, "/micro/config")
   if err != nil {
      fmt.Printf("Init consulConfig failed, err: %v\n", err)
   }
   // 2.注册中心
   consulRegistry := consul.NewRegistry(func(options *registry.Options) {
      options.Addrs = []string{
         "127.0.0.1:8500",
      }
   })
   if err := micro2.GetAccountFromConsul(consulConfig, "account"); err != nil {
      fmt.Printf("Init consul failed, err: %v\n", err)
   }
   fmt.Println(micro2.ConsulInfo)
   // 3.zap日志初始化
   if err := logger.Init(); err != nil {
      fmt.Printf("Init logger failed, err: %v\n", err)
      return
   }
   defer zap.L().Sync()
   // 5.初始化数据库
   db, err := mysql.MysqlInit(micro2.ConsulInfo.Mysql.User, micro2.ConsulInfo.Mysql.Pwd, micro2.ConsulInfo.Mysql.Database)
   if err != nil {
      logger.Error(err)
      return
   }
   defer db.Close()
   // 创建实例
   accountService := service.NewUserService(repository.NewUserRepository(db))
   // 6.初始化Redis连接
   if err := redis.Init(); err != nil {
      logger.Error(err)
      return
   }
   defer redis.Close()
   // 8.注册服务
   registryService := micro.NewService(
      micro.Name(micro2.ConsulInfo.Micro.Name),
      micro.Version(micro2.ConsulInfo.Micro.Version),
      //暴露的服务地址
      micro.Address(micro2.ConsulInfo.Micro.Address),
      //添加consul 注册中心
      micro.Registry(consulRegistry),
   )
   // 9.初始化服务
   registryService.Init()
   // 10.注册Handle
   account.RegisterAccountHandler(registryService.Server(), &handler.Account{AccountService: accountService})
   // 11.启动服务
   if err := registryService.Run(); err != nil {
      logger.Fatal(err)
   }
}
  • 至此,可以运行项目了,运行成功后出现下图,即可开发成功

  • 记得把consul运行起来,因为项目中使用了consul

  • 如果报错,可以私信博主或者加入博主的学习交流裙询问都可

image.png

十二 最后

  • 至此,go-micro微服务项目main.go开发工作就正式完成。

  • 接下来就开始jaeger链路追踪的代码编写了,希望大家关注博主和关注专栏,第一时间获取最新内容,每篇博客都干货满满。

欢迎大家加入 夏沫の梦的学习交流群 进行学习交流经验,点击 夏沫の梦学习交流

本文转载于网络 如有侵权请联系删除

相关文章

  • 你有没有掉进去过这些Spring MVC中的“陷阱“(上)

    一、自定义返回HTTP状态码  当浏览器输入一个URL地址时,浏览器会向服务器发出请求,在浏览器接收和显示响应内容之前,服务器会返回一个包含HTTP状态码的响应头,响应浏览器的请求。动态码是一个标识,标识当前响应的状态成功或者失败或者需要进行进行其他操作。常见的HTTP状态码有200、302、404、500等HTTP状态码有以下五种类型,HTTP状态码的第一位表示状态码的类型:1xx:服务器收到客户端的请求,需要客户端继续执行操作2xx:请求成功3xx:重定向,需要进一步的操作完成请求4xx:客户端出错,请求出错5xx:服务区错误,请求处理发生错误而我们在编写基于SpringMVC的程序时并没有定义响应的状态码,这是因为SpringMVC已经在框架中定义好了这些响应码,不需要在编写业务代码时再去定义响应码,当然SpringMVC也支持自定义状态码需要自定义返回状态码的场景有以下几种针对不容的错误类型发送特定的错误码客户端的定制化需求SpringMVC中自定义返回状态码的方式有以下几种:使用ResponseEntity表示状态码、头部信息、响应体Con

  • tp6注解路由安装报错了咋整?怎么写一个简单的注解路由

    作者:陈业贵华为云享专家51cto(专家博主明日之星TOP红人)文章目录前言一、安装注解路由(报错是因为不指定版本)2.代码效果tp6框架结构切记,使用注解路由时,index应用下的route文件夹要重命名为其他的,不然不能生效前言关于注解路由的基本使用+安装注解路由一、安装注解路由(报错是因为不指定版本)composerrequiretopthink/think-annotation^1.0复制2.代码<?php declare(strict_types=1); namespaceapp\index\controller;//命名空间,以app开始文件夹开始,controller结束 usethink\annotation\Route;//注解路由的引用 classIndex { /** *@paramstring$name数据名称 *@returnmixed *@Route("hello/:name") */ //注解路由:hello方法的:name参数,也就是这里的cyg publicfunctionhello($name)//套用tp6文档的代码

  • riscv gcc中添加自定义的csr支持

    riscvgcc中添加自定义的csr支持1.概述2.不改变编译工具链实现CSR添加3.在编译器中集成CSR名称4.编译开发riscvgcc相关5.小结1.概述由于RISCV的模块化的指令集的定义,各家都有着自己的实现方式。从当前看来,除了标准的CSR外,很多都实现了自己的CSR指令扩展。如何自定义CSR并且让编译器能够识别,本文将进行一定的分析,同时从riscvgcc开发的角度出发,来分析编译器开发的流程。2.不改变编译工具链实现CSR添加如果想读写CSR,可以使用汇编指令进行操作。voidtest_csr() { inta=0x00200; asmvolatile("csrw0x307,%0"::"r"(a)); } 复制通过反汇编riscv32-unknown-elf-objdump-Dvirt_test.elf>1.txt 复制得到该函数的汇编代码由于编号为0x307的CSR没有标准定义,所以会直接会体现在汇编函数中。但是这样并不会影响功能的使用。对于这些非标准的CSR的读写操作,RISCVGCC并不会根据特定的编码序号生成相应的名称

  • 【目标检测】开源 | 吊打一切的 YOLOv4它来了

    论文地址:http://arxiv.org/pdf/2004.10934v1.pdf 代码:https://github.com/alexeyab/darknet 论文名称:YOLOv4:OptimalSpeedandAccuracyofObjectDetection 原文作者:AlexeyBochkovskiy、Chien-YaoWang和Hong-YuanMarkLiao当前随着深度学习算法的的快速发展,出现了很多特征提取网络结构,可以提高算法的精度。但是需要在大数据集上对这些特征组合进行实际测试,并对结果进行理论验证。有些特征专门针对某些模型和某些问题,或者只针对小规模数据集;而一些其他的模型,如批处理标准化和剩余连接,适用于大多数模型、任务和数据集等。本文假设这些通用的模型包括:Weighted-Residual-Connections(WRC),Cross-Stage-Partial-connections(CSP),Crossmini-BatchNormalization(CmBN),Self-adversarial-training(SAT)andMish-activat

  • [财务][数据化分析][帆软]报表设计-普通报表设计

    1.描述普通报表设计可以分为报表设计、参数设计、图表设计和填报设计四个部分,这四个部分是FineReport普通模板的几大使用方式。普通报表的特点有:类Excel设计界面、无限行列扩展和多sheet功能,能轻松实现数据间的各种运算,实现复杂表样、分组交叉、卡片分栏、同比环比等功能。同时普通报表还存在一些不足:局限于规整的格子式报表和不支持局部刷新等。1.1报表设计报表设计是纯粹的数据展示,如下图:详细使用方法请参照 报表设计;1.2参数设计参数设计是动态查询数据,如下图所示: 详细使用方式请参照 参数入门;1.3图表设计图表设计是使用图表来展示数据,如下图所示:详细使用方式请参照 图表入门;1.4填报设计填报设计是录入数据,将数据写入数据库中,如下图:详细使用方式请参照 填报入门。根据实际情况确定使用哪一张使用方式,或者联合使用哪几种使用方式。

  • 素数案例-高职考VB技能提升

    本期知识视频教程视频内容文字讲解: 素数其实就是我们平时说的质数。 在一般领域,对正整数n,如果用2到√n(根号n)之间的所有整数去除,均无法整除,则n为质数。做一个案例吧!案例~根据题意来填空: 根据这个题目,我们来设计并制作一下这个案例。 首先来按照题目意思来设计一下: 文本框相关设置:–1、multiline选择true代表可以多行写。–2、scrollbar选2代表打开纵向滚动条。相关属性: 求解按钮随意设计一下,题目中没有要求,那就没有关系。 双击“求解”按钮,下面开始码代码:首先,在点击求解的时候,我们让文本框清空。使用如下代码:Text1.Text="" 然后,我们解释题目中出现的几个函数的意思。 Sqr函数:求平方根Chr(13):\r回车键Chr(10):\n换行Int函数:向下取整题目分析:这个题目是要输出3至100之间所有的为素数的数字有哪些。 K=Int(Sqr(n))表示获取当前这个数的平方根,并进行向下取整后返回值存放到K变量。i=2是因为判断一个数为素数,只要从2开始除就可以了。flag=0'标记0默认为素数,1表示非素数内部

  • Python获取本机 IP/MAC(多网

      Python获取本机IP地址的一般方法为import socket IP = socket.gethostbyname(socket.gethostname())复制  通过gethostname获取主机名,再用gethostbyname将主机名转换为IP地址。  那么,问题来了。如果主机有多个网卡/IP,怎样获取某个指定的IP地址呢?  一个方法是通过socket.gethostbyname_ex获取主机IP地址列表,然后遍历列表取得自己需要的IP。import socket #多网卡情况下,根据前缀获取IP(Windows 下适用) def GetLocalIPByPrefix(prefix): localIP = '' for ip in socket.gethostbyname_ex(socket.gethostname())[2]: if ip.startswith(prefix): localIP = ip return localIP print(GetLocalIPByPrefix('192.168&#x

  • go Http Post 发送文件流

    packagemain import( "net/http" "net/url" "fmt" "io/ioutil" _"io" "bytes" ) funcmain(){ postFile() } funcpost(){ //这是一个Post参数会被返回的地址 strinUrl:="http://localhost:8080/aaa"`这里写代码片` resopne,err:=http.PostForm(strinUrl,url.Values{"num":{"456"},"num1":{"123"}}) iferr!=nil{ fmt.Println("err=",err) } deferfunc(){ resopne.Body.Close() fmt.Println("finish") }() body,err:=iou

  • hdu1078 zoj1107(记忆化搜索/DP)

    大家好,又见面了,我是你们的朋友全栈君。题目链接:zojhdu题目大意:老鼠从(0,0)出发,每次在同一个方向上最多前进k步,且每次到达的位置上的数字都要比上一个位置上的数字大,求老鼠经过的位置上的数字的和的最大值#include<stdio.h> #include<string.h> #definemax(a,b)a>b?a:b intn; intk;//前进的步数 intmap[105][105]; intans[105][105];//记忆化搜索,保存中间搜索结果 intsearch(intx,inty) { intdx,dy;//要去的下一个位置 inti,maxx=0; if(ans[x][y]!=-1)returnans[x][y];//已经搜索过,直接返回结果 for(i=1;i<=k;i++)//向前走的步数 { dx=x-i;//向上 if(dx>=0&&dx<n&&map[dx][y]>map[x][y]) { ans[dx][y]=search(dx,y); maxx=max(m

  • C++异常处理: try,catch,throw,finally的用法

      写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使用过异常,但是你习惯使用异常了吗? 现在很多软件都是n*365*24小时运行,软件的健壮性至关重要.  内容导读本文包括2个大的异常实现概念:C++的标准异常和SEH异常. C++标准异常: 也许你很高兴看到错误之后的Heap/Stack中对象被释放,可是如果没有呢? 又或者试想一下一个能解决的错误,需要我们把整个程序Kill掉吗? 在《C++标准异常》中我向你推荐这几章: <使用异常规格编程><构造和析构中的异常抛出><使用析构函数防止资源泄漏>,以及深入一点的<抛出一个异常的

  • 这数据库的结构设计,还能再糟糕一点吗?

    聊聊一个糟糕的数据库架构设计带来的问题。技术人人都可以磨炼,但处理问题的思路和角度各有不同,希望这篇文章可以抛砖引玉。以一个例子为切入点 一、问题背景某系统已经线上运行多年,数据量随着时间的推移越来越大。公司业务量还在不断增加,已经潜在威胁数据库的运行效率,急需清理历史数据。基础环境: 主机类型:云环境  操作系统:CentOSrelease7.8 存储:EMC 内存:128G CPU型号:Intel(R)Xeon(R)Platinum8163CPU@2.50GHz(1U*8core)  CPU核数:32CORE 数据库环境:11.2.0.4 问题现象:对某个百G大表进行清理时出现了问题。简单说明:在很多应用场景中,SQL的性能直接决定了系统的性能。此外,查询速度慢并不只是因为SQL语句本身,还可能是因为内存分配不佳、文件结构不合理、优化器判断异常等其他原因。本文介绍一些通过调整SQL语句就能优化SQL的通用小技巧,优化SQL的方法不能解决所有的性能问题,但是却能处理很多因SQL写法不合理而产生的性能问题。二、分析说明 通过分析定位问题,分析问题原因; 追

  • java List排序 顺序 倒序 随机

    Listlist=newLinkedList(); for(inti=0;i<9;i++){ list.add("a"+i); } Collections.sort(list);//顺序排列 System.out.println(list); Collections.shuffle(list);//混乱的意思 System.out.println(list); Collections.reverse(list);//倒序排列 System.out.println(list); System.out.println(Collections.binarySearch(list,"a5"));//折半查找复制  

  • 旋转图像

    给定一个n×n的二维矩阵matrix表示一个图像。请你将图像顺时针旋转90度。你必须在原地旋转图像。 defrotate(matrix): """ 先对矩阵做转置,然后把每一行颠倒,就可以达到将图像旋转90度的效果。 """ n=len(matrix) foriinrange(n): forjinrange(i,n): matrix[i][j],matrix[j][i]=matrix[j][i],matrix[i][j] foriinrange(n): matrix[i]=matrix[i][::-1] 复制

  • Markdown 标记语言指北

    这是班刊约稿的一篇文章. 全文约6000字,预计需要60分钟读完. Markdown标记语言指北 TOC 什么是Markdown? Markdown可以用来干什么? 第一步? 一些专业一点的内容 Markdown的简要语法 GFM? 段落 标题 文字的修饰 段落的修饰 列表 插入 1.超链接 2.图片 表格 进阶的应用 数学公式 代码 嵌入HTML 扩展的Markdown 总结 后记 关于 Reference Abstract Markdown\(^1\)创造于2004年,是网络上最常用的用于编写文档的语言之一.这篇文章作为一篇指南,简要介绍了Markdown标记语言的语法和原理,以及利用它撰写文档的一些实践.同时,本文也涉及到一些数学公式排版的内容与\(\TeX\)排版引擎的原理. 什么是Markdown? 9102年了,你还在用MicrosoftWord写文档吗?(大雾) 毫无疑问,MSWord是这个星球上通用性最强,功能最强大的文字处理软件.秉承着所见即所得\(^2\)(WhatYouSeeIsWhatYouGet,WYSIWYG)的精神,它提供了一流的写作与排版体验.

  • ubuntu服务器环境配置参考

    一、基本的Linux系统命令: ls查看当前目录下的文件及文件夹 cd/var/www/html转换目录到/var/www/html cdabc/ddd/转换目录到当前目录下的abc文件夹下的ddd文件夹 sudo在其他命令前加本命令以提升命令的运行权限(安装软件的时候必须加,在没有读写权限的目录下操作必须加)。 sudoapt-getinstallXXX安装XXX软件(该软件需在库中) sudoapt-searchcacheXXX查看当前库中XXX软件(前缀查询,会罗列名字前缀相同的软件) sudoapt-getremoveXXX卸载XXX sudoapt-getautoremove智能卸载用不到的库文件和软件组件。 mvabc/aabb/b将当前目录下abc文件夹中的a文件移动到当前目录下abb文件夹中,命名为b(可用做该改名) cpabc/aabb/b将当前目录下abc文件夹中的a文件复制到当前目录下abb文件夹中,命名为b mkdira/在当前目录下创建文件夹a复制   一.五、vim编辑器 ubuntu下的编辑器是vim 在终端中键入:

  • python1加到n

    1whileTrue: 2a=0 3n=input('从0开始加到您所输入的数字:') 4ifn.isdigit()==True: 5n=int(n) 6foriinrange(n+1): 7a+=i 8else: 9print('计算完成,结果为',a) 10s=input('输入q退出或者任意字符继续:') 11ifs=='q': 12break 13else: 14print('请输入正整数!') 15print('程序结束!')复制  

  • 博客迁移至wordpress--http://i1994898w1.imwork.net/wordpress

    即日起,博文迁移至wordpress架设小站。http://i1994898w1.imwork.net/wordpress OPTIMISM,PASSION&HARDWORK

  • Python3—元组

    python3的元组和列表类似,不同之处在于元组的元素不能修改。 元组使用的是(),列表使用的[]。 例子:  当元组内只包含一个元素的话,需要在后边加上一个逗号,否则括号会被当做运算符使用。例子: 元组的操作: 一、访问元组   元组和字符串类似,下标索引从0开始,可以进行截取、组合等。    二、修改元组   元组中的元素是不允许进行修改的,但我们可以对元组进行连接组合,例子:    三、删除元组   元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,例子:      在次进行数据类型的打印的时候,就会报错,因为此时tup1元组已经被删除掉了。   但可以使用空的()来进行重新定义。例子:      四、元组的运算符   与字符串一样,元组之间可用使用+号和*号进行运算,可进行组合和复制,组合成为一个新的元组   tup=(1,2,3,)   tup1=(4,5)   1.len(tup):计算出元素的个数。3个。   2.tup+tup1:连接。输出(1,2,3,4,5)   3.tup1*2:复制。输出

  • UNCTF2020-WEB:ezphp(array反序列化)

    源码: <?php show_source(__FILE__); $username="admin"; $password="password"; include("flag.php"); $data=isset($_POST['data'])?$_POST['data']:""; $data_unserialize=unserialize($data); echo if($data_unserialize['username']==$username&&$data_unserialize['password']==$password){ echo$flag; }else{ echo"usernameorpassworderror!"; }复制     一开始尝试使用array序列化一个账号密码为admin和passowrd的对象 data=a:2:{s:8:"username";s:5:"admin";s:8:"password";s:8:"password";}复制 结果在本地运行可以了,在线exp就不行 后来仔细看源码发现&nbs

  • Redis Sentinel的Redis集群(主从&amp;Sharding)高可用方案

    在不使用redis3.0之后版本的情况下,对于redis服务端一般是采用Sentinel哨兵模式,也就是一主多备的方式。 这里,先抛出三个问题, 问题1:单节点宕机数据丢失?问题2:多节点(节点间没有主从关系)数据分片,采用sharedJedisPool,某节点宕机,导致获取不到连接问题3:主从模式下,通过哨兵配置,单个集群数据无法分片(备复制->主的数据,备无写权限)   关于问题1,解决方式,多台redis节点,采用Sentinel哨兵模式,也就是一主多备的方式。 关于问题2,这里先不谈解决方式,在节点间无依赖的情况下,采用redis分片存储数据,也就是采用redis的sharedjedispool连接池,他有一个缺点,那就是当我的某个 节点宕机后,会导致整个连接出问题。 关于问题3,在一个集群环境下,从复制主的数据,这个时候一个集群下的redis实例之间的数据是同步,也就没有办法去做数据分片 在不适用redis3.0后的新特征loadbalance,也就是.... RedisCluster 是Redis的集群实现,内置数据自动分片机制,集群内部将所有的k

  • 【转】遗传算法详解(GA)

    遗传算法(GeneticAlgorithm,GA)起源于对生物系统所进行的计算机模拟研究。它是模仿自然界生物进化机制发展起来的随机全局搜索和优化方法,借鉴了达尔文的进化论和孟德尔的遗传学说。其本质是一种高效、并行、全局搜索的方法,能在搜索过程中自动获取和积累有关搜索空间的知识,并自适应地控制搜索过程以求得最佳解。 相关术语: 基因型(genotype):性状染色体的内部表现; 表现型(phenotype):染色体决定的性状的外部表现,或者说,根据基因型形成的个体的外部表现; 进化(evolution):种群逐渐适应生存环境,品质不断得到改良。生物的进化是以种群的形式进行的。 适应度(fitness):度量某个物种对于生存环境的适应程度。 选择(selection):以一定的概率从种群中选择若干个个体。一般,选择过程是一种基于适应度的优胜劣汰的过程。 复制(reproduction):细胞分裂时,遗传物质DNA通过复制而转移到新产生的细胞中,新细胞就继承了旧细胞的基因。 交叉(crossover):两个染色体的某一相同位置处DNA被切断,前后两串分别交叉组合形成两个新的染色体。也称基因

相关推荐

推荐阅读