服务注册与发现consul

1. 介绍

  1. 微服务中使用的服务注册发现中心

  2. 同类有etcd、eureka等

2. 简单使用

  1. 在docker中运行

  • 在后台运行,要重新进入的话:docker exec -it fe693be00668 /bin/sh

    	docker run -d --name=consultest -p 8500:8500 consul:latest agent -server -bootstrap -ui -client 0.0.0.0
    • -server表示以服务端的方式启动

    • -bootstrap表示指定自己为leader,而不需要选举

    • -ui启动一个内置管理web页面

    • -client指定客户端可以访问的ip,默认只能本地访问,设置0.0.0.0可以任意访问。

  1. 手动注册服务

  • consul services register -name=web 创建一个默认的没啥用的服务

  • 使用json文件制定服务:consul services register web.json

    	{
      "Service": {
        "ID":"userservice",
        "Name":"userservice",
        "Tag":[
                "primary"
        ],
        "Address":"127.0.0.1",
        "Port":8999,
        "Check":{
                "HTTP":"http://127.0.0.1:8999/health",
                "Interval":"5s"
        }
      }
    }
  1. 删除注册

  • consul services deregister -id=web 根据id

  • consul services deregister web.json 根据json配置文件

go操作consul

1. 注册服务与取消注册

2. 获得consul服务信息

  1. 使用consul客户端的api来操作

3. 设置负载均衡

  1. 轮询

  2. 随机

    • 通过修改lb包下random.go的源码

4. api限流

1. 限流作用

2. 限流常用算法

  1. 漏桶

    • 漏桶生成令牌的速度恒定,出桶的速度也是恒定的,意味着如果瞬间有大量请求过来,则大部分会被丢弃。

    • 令牌桶生成令牌的速度是恒定的,而请求去拿令牌是没有速度限制的。这意味,面对瞬时大流量,该算法可以在短时间内请求拿到大量令牌,而且拿令牌的过程并不是消耗很大的事情。

  2. 令牌桶

    • 以恒定的速度生成token

    • 请求先拿token,拿到后才能进行业务处理,否则阻塞等待

    • token没有标识用户信息的意义,只是当做令牌

3. 令牌桶:go有个内置的限流包rate

  1. rate.NewLimiter(1,5)创建一个容量为5,没1s生成一个token的桶

  2. Wait/WaitN

    • 这个N指的是每次消耗几个token,令牌不够就阻塞等待

  3. Allow/AllowN

    • 不阻塞,令牌不够返回false,继续执行

  4. Reserve/ReserveN

    • 这个N指的是每次消耗几个token

  5. 使用方式

    • 对请求处理前判断一下,如果拿到令牌就执行

5. 熔断

1. 介绍

  1. 本质是:隔离远程服务请求,防止级联故障。出现错误能让服务继续运行,防止崩溃。

2. 处理库:hystrix-go

  1. 地址:https://github.com/afex/hystrix-go

  2. 可以对执行函数进行监控和错误处理,比如超时了怎么处理

  3. 可以同步处理错误,也可以异步处理(需要使用通道)

  4. 可以限制的参数:

    • 超时

    • 并发数

3. 服务降级

  1. 如超时降级,就是利用hystrix-go检测到超时后,错误处理中进行其他默认处理。

4. 熔断器

  1. 可以设置错误比例,比如超时超过10%,才打开熔断器进行出错服务降级等操作。

6. JWT

0. go操作JWT

  1. 库地址:github.com/dgrijalva/jwt-go

1. 介绍

  1. JSON WEB TOKEN

  2. 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

2. 传统的session认证

  1. 在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于session认证。

  2. 但是这种基于session的认证使应用本身很难得到扩展,随着不同客户端用户的增加,独立的服务器已无法承载更多的用户,而这时候基于session认证应用的问题就会暴露出来.

  3. 基于session认证所显露的问题

    • Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

    • 扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

    • CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

3. 基于token的鉴权机制

  1. 基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

  2. 流程

    • 用户使用用户名密码来请求服务器

    • 服务器进行验证用户的信息

    • 服务器通过验证发送给用户一个token

    • 客户端存储token,并在每次请求时附送上这个token值

    • 服务端验证token值,并返回数据

  3. 这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了Access-Control-Allow-Origin: *。

4. JWT的构成

  1. JWT是由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串。就像这样:

  2. header

    • jwt的头部承载两部分信息:

      • 声明类型,这里是jwt

      • 声明加密的算法 通常直接使用 HMAC SHA256

  3. playload

    • 载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分:标准中注册的声明,公共的声明,私有的声明

    • 定义一个payload:

    • 然后将其进行base64加密,得到Jwt的第二部分。

  4. signature

    • jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

      • header (base64后的)

      • payload (base64后的)

      • secret

5. 如何应用JWT

  1. 一般是在请求头里加入Authorization,并加上Bearer标注:

6. 总结

  1. 优点

    • 因为json的通用性,所以JWT是可以进行跨语言支持的,像 JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。

    • 因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。

    • 便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。

    • 它不需要在服务端保存会话信息, 所以它易于应用的扩展

  2. 安全相关

    • 不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。

    • 保护好secret私钥,该私钥非常重要。

    • 如果可以,请使用https协议

文档

  1. https://www.consul.io/api-docs

最后更新于