Golang 微服务实例求解

本贴最后更新于 2156 天前,其中的信息可能已经东海扬尘

最近在看微服务,了解到一个微服务应用是多个后台服务组合起来的应用,这些个后台服务有自己的接口,自己的处理器,自己的数据库等。
概念看了很多,也有那么一丝丝理解,跟着一篇文档敲了一次代码,感觉下来还是一个单体应用,丝毫没有看到微服务的影子呀。。
代码如下:

`package main`
`import ( `
`"encoding/json"`
`"fmt"`
`"log"`
`"net/http"`
`"goji.io"`
`"goji.io/pat"`
`"gopkg.in/mgo.v2"`
`"gopkg.in/mgo.v2/bson"`
`)`
`func ErrorWithJSON(w http.ResponseWriter, message string, code` `int``) { `
`w.Header().Set(``"Content-Type"``,` `"application/json; charset=utf-8"``)`
`w.WriteHeader(code)`
`fmt.Fprintf(w,` `"{message: %q}"``, message)`
`}`

`func ResponseWithJSON(w http.ResponseWriter, json []byte, code` `int``) { `
`w.Header().Set(``"Content-Type"``,` `"application/json; charset=utf-8"``)`
`w.WriteHeader(code)`
`w.Write(json)`
`}`

`type Book` `struct` `{ `
`ISBN    string   `json:``"isbn"
`Title   string   `json:``"title"
`Authors []string `json:``"authors"
`Price   string   `json:``"price"
`}`

`func main() { `
`session, err := mgo.Dial(``"localhost"``)`
`if` `err != nil {`
`panic(err)`
`}`
`defer session.Close()`
`session.SetMode(mgo.Monotonic,` `true``)`
`ensureIndex(session)`
`mux := goji.NewMux()`
`mux.HandleFunc(pat.Get(``"/books"``), allBooks(session))`
`mux.HandleFunc(pat.Post(``"/books"``), addBook(session))`
`mux.HandleFunc(pat.Get(``"/books/:isbn"``), bookByISBN(session))`
`mux.HandleFunc(pat.Put(``"/books/:isbn"``), updateBook(session))`
`mux.HandleFunc(pat.Delete(``"/books/:isbn"``), deleteBook(session))`
`http.ListenAndServe(``"localhost:8080"``, mux)`
`}`

`func ensureIndex(s *mgo.Session) { `
`session := s.Copy()`
`defer session.Close()`
`c := session.DB(``"store"``).C(``"books"``)`
`index := mgo.Index{`
`Key:        []string{``"isbn"``},`
`Unique:` `true``,`
`DropDups:` `true``,`
`Background:` `true``,`
`Sparse:` `true``,`
`}`
`err := c.EnsureIndex(index)`
`if``err != nil {`
`panic(err)`
`}`

`}`

`func allBooks(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`c := session.DB(``"store"``).C(``"books"``)`
`var books []Book`
`err := c.Find(bson.M{}).All(&books)`
`if` `err != nil {`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed get all books: "``, err)`
`return`
`}`
`respBody, err := json.MarshalIndent(books,` `""``,` `"  "``)`
`if` `err != nil {`
`log``.Fatal(err)`
`}`
`ResponseWithJSON(w, respBody, http.StatusOK)`
`}`
`}`

`func addBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`var book Book`
`decoder := json.NewDecoder(r.Body)`
`err := decoder.Decode(&book)`
`if` `err != nil {`
`ErrorWithJSON(w,` `"Incorrect body"``, http.StatusBadRequest)`
`return`
`}`
`c := session.DB(``"store"``).C(``"books"``)`
`err = c.Insert(book)`
`if` `err != nil {`
`if` `mgo.IsDup(err) {`
`ErrorWithJSON(w,` `"Book with this ISBN already exists"``, http.StatusBadRequest)`
`return`
`}`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed insert book: "``, err)`
`return`
`}`
`w.Header().Set(``"Content-Type"``,` `"application/json"``)`
`w.Header().Set(``"Location"``, r.URL.Path+``"/"``+book.ISBN)`
`w.WriteHeader(http.StatusCreated)`
`}`
`}`

`func bookByISBN(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`isbn := pat.Param(r,` `"isbn"``)`
`c := session.DB(``"store"``).C(``"books"``)`
`var book Book`
`err := c.Find(bson.M{``"isbn"``: isbn}).One(&book)`
`if` `err != nil {`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed find book: "``, err)`
`return`
`}`
`if` `book.ISBN ==` `""` `{`
`ErrorWithJSON(w,` `"Book not found"``, http.StatusNotFound)`
`return`
`}`
`respBody, err := json.MarshalIndent(book,` `""``,` `"  "``)`
`if` `err != nil {`
`log``.Fatal(err)`
`}`
`ResponseWithJSON(w, respBody, http.StatusOK)`
`}`
`}`

`func updateBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`isbn := pat.Param(r,` `"isbn"``)`
`var book Book`
`decoder := json.NewDecoder(r.Body)`
`err := decoder.Decode(&book)`
`if` `err != nil {`
`ErrorWithJSON(w,` `"Incorrect body"``, http.StatusBadRequest)`
`return`
`}`
`c := session.DB(``"store"``).C(``"books"``)`
`err = c.Update(bson.M{``"isbn"``: isbn}, &book)`
`if` `err != nil {`
`switch` `err {`
`default``:`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed update book: "``, err)`
`return`
`case` `mgo.ErrNotFound:`
`ErrorWithJSON(w,` `"Book not found"``, http.StatusNotFound)`
`return`
`}`
`}`
`w.WriteHeader(http.StatusNoContent)`
`}`
`}`

`func deleteBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) { `
`return` `func(w http.ResponseWriter, r *http.Request) {`
`session := s.Copy()`
`defer session.Close()`
`isbn := pat.Param(r,` `"isbn"``)`
`c := session.DB(``"store"``).C(``"books"``)`
`err := c.Remove(bson.M{``"isbn"``: isbn})`
`if` `err != nil {`
`switch` `err {`
`default``:`
`ErrorWithJSON(w,` `"Database error"``, http.StatusInternalServerError)`
`log``.Println(``"Failed delete book: "``, err)`
`return`
`case` `mgo.ErrNotFound:`
`ErrorWithJSON(w,` `"Book not found"``, http.StatusNotFound)`
`return`
`}`
`}`
`w.WriteHeader(http.StatusNoContent)`
`}`
`}`

希望各位大佬给点入门指导或者建议,最好有代码 demo,可以便于理解,我是越看越模糊了。

  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    492 引用 • 1383 回帖 • 375 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    6554 引用 • 29426 回帖 • 246 关注
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • james

    估计你单个应用是体现不出来的,我们这里是有一个中心的服务注册中心,服务会注册 IP 端口等这些信息,然后各个服务通过服务名,接口到注册中心查服务信息,发送请求给各个服务。不是各个服务直接通信,中间通过一个代理来做。

    1 回复
  • 其他回帖
  • auuunnya
    作者

    那么如果要在加一个服务,例如:注册,在这个代码上应该怎么做扩展,代理我也看了一般的话就是用的中间代理 apigetway,这个代理是不是就是一个一个的路由?

    1 回复
  • james

    要先把微服务框架写好,提供好 SDK。你新加一个服务,就只要调用 SDK 的时候给出服务名,本机 IP,端口。SDK 里面去做服务注册,心跳注册。
    服务调用也使用统一好的 SDK,调用的时候给出服务名,接口名,参数。SDK 厘米做服务查询,发现,发送请求,解析请求等。
    这样新加服务,及调用服务完全屏蔽调微服务层,扩展就很简单了。调用也简单,你都不用写 httpclient 就能请求获取相应。先把相应 SDK 封装好,就会好很多。

推荐标签 标签

  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 693 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    75 引用 • 145 回帖 • 1 关注
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖
  • Sillot

    Sillot (汐洛)孵化自思源笔记,致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点
    Github 地址:https://github.com/Hi-Windom/Sillot

    15 引用 • 6 回帖 • 28 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    70 引用 • 532 回帖 • 712 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    51 引用 • 37 回帖
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    4 引用 • 55 回帖 • 10 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 18 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    131 引用 • 3639 回帖
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    140 引用 • 441 回帖 • 1 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    261 引用 • 662 回帖
  • 反馈

    Communication channel for makers and users.

    123 引用 • 906 回帖 • 193 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 126 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 89 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖 • 2 关注
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 47 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 28 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 6 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    164 引用 • 407 回帖 • 526 关注
  • 音乐

    你听到信仰的声音了么?

    59 引用 • 509 回帖
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    675 引用 • 535 回帖 • 1 关注
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 10 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 2 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 592 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1425 引用 • 10043 回帖 • 470 关注