为了提升 Dubbo 里程碑版本2.7.0的使用体验,我们于去年年中启动了 Dubbo Admin 的重构计划,并作为Dubbo生态的子项目,于近期发布了v0.1,重构后的项目在结构上的变化如下:
  
  将后端框架从webx替换成spring boot
  
  前端采用Vue和Vuetify.js作为开发框架
  
  移除velocity模板
  
  集成swagger,提供api管理功能
  
  当前版本的Dubbo Admin包含了之前版本中的绝大部分功能,包括服务治理,服务查询等,同时支持了Dubbo2.7中服务治理的新特性。
  
  配置规范
  
  由于在Dubbo2.7中,配置中心和注册中心做了分离,并且增加了元数据中心,因此Dubbo Admin的配置方式也做了更新,application.properties中的配置如下:
  
  admin.registry.address=zookeeper://127.0.0.1:2181
  
  admin.config-center=zookeeper://127.0.0.1:2181
  
  admin.metadata.address=zookeeper://127.0.0.1:2181
  
  也可以和Dubbo2.7一样,在配置中心指定元数据和注册中心的地址,以zookeeper为例,配置的路径和内容如下:
  
  # /dubbo/config/dubbo/dubbo.properties
  
  dubbo.registry.address=zookeeper://127.0.0.1:2181
  
  dubbo.metadata-report.address=zookeeper://127.0.0.1:2181
  
  配置中心里的地址会覆盖掉本地application.properties的配置
  
  功能介绍
  
  功能上,主要延续了之前版本的功能,包括服务查询和服务治理,2.7版本在服务治理的功能上有了很大的改进,这些改进也大部分都会以Dubbo Admin作为入口来体现。
  
  标签路由
  
  标签路由是Dubbo2.7引入的新功能,配置以应用作为维度,给不同的服务器打上不同名字的标签,配置如下图所示:
  
  1548675129621_1f2f3f68_4f35_4105_97e2_c4a0d7dc62c8_jpeg
  
  调用的时候,客户端可以通过setAttachment的方式,来设置不同的标签名称,比如本例中,setAttachment(tag1),客户端的选址范围就在如图所示的三台机器中,可以通过这种方式来实现流量隔离,灰度发布等功能。
  
  应用级别的服务治理
  
  在Dubbo2.6及更早版本中,所有的服务治理规则都只针对服务粒度,如果要把某条规则作用到应用粒度上,需要为应用下的所有服务配合相同的规则,变更,删除的时候也需要对应的操作,这样的操作很不友好,因此Dubbo2.7版本中增加了应用粒度的服务治理操作,对于条件路由(包括黑白名单),动态配置(包括权重,负载均衡)都可以做应用级别的配置:
  
  1548675095660_2abe00e4_7a3c_4c49_8649_0cc81e00e324_jpeg
  
  上图是条件路由的配置,可以按照应用名,服务名两个维度来填写,也可以按照这两个维度来查询。
  
  1548675169501_57b22613_ba3a_462b_b3ba_af34ea778589_jpeg
  
  条件路由,标签路由和动态配置都采用了yaml格式的文本编写,其他的规则配置还是采用了表单的形式。
  
  关于兼容性
  
  Dubbo2.6到Dubbo2.7,服务治理发生了比较大的变化,Dubbo Admin兼容两个版本的用法:
  
  对于服务级别的配置,会按照Dubbo2.6(URL)和Dubbo2.7(配置文件)两种格式进行写入,保证Dubbo2.6的客户端能够正确读取,解析规则
  
  对于应用级别的配置,包括标签路由,只会按照Dubbo2.7的格式进行写入,因为Dubbo2.6无此功能,不需要做向前兼容。
  
  Dubbo Admin只会按照Dubbo2.7的格式进行配置读取,因此,所有在Dubbo Admin上做的配置都可以被读到,但是之前遗留的,Dubbo2.6格式的URL无法被读取。
  
  对于同一个应用或者服务,每种规则只能够配置一条,否则新的会覆盖旧的。
  
  配置管理
  
  配置管理也是配合Dubbo2.7新增的功能,在Dubbo2.7中,增加了全局和应用维度的配置。
  
  全局配置:
  
  1548675196442_4611bfd9_5077_4bd2_a2b1_ad89c5eefc13_jpeg
  
  全局配置里可以指定注册中心,元数据中心的地址,服务端和客户端的超时时间等,这些配置在全局内生效。除了配置写入,也可以用来查看。如果使用zookeeper作为注册中心和元数据中心,还可以看到配置文件所在位置的目录结构。
  
  应用和服务配置
  
  1548675223170_772fd97b_f49f_4cf6_be40_34355f8159a1_jpeg
  
  应用级别的配置可以为应用或者应用内的服务指定配置,在服务维度上,需要区分提供者和消费者。dubbo.reference.{serviceName}表示作为该服务消费者的配置,dubbo.provider.{servcieName}表示作为该服务提供者的配置。优先级服务 > 应用 > 全局。其中注册中心和元数据中心的地址,只能在全局配置中指定,这也是Dubbo2.7中推荐的使用方式。
  
  元数据和服务测试
  
  元数据是Dubbo2.7中新引入的元素,主要的使用场景就在Dubbo Admin中,主要体现在两个地方:
  
  服务详情展示:
  
  1548675234502_67cefa2f_e180_4715_a203_a98bf515fe4f_jpeg
  
  跟之前版本相比,Dubbo2.7中增加了对服务方法完整签名的记录,因此服务详情中也增加了方法信息的详情,可以看到方法名,方法参数列表以及返回值信息。
  
  服务测试:
  
  1548675056214_730b7a7b_d4af_4a57_ab3f_380c5afcdabb_jpeg
  
  更重要的,元数据为服务测试提供了数据基础,可以在页面上调用真实的服务提供者,方便测试,也不需要为了调用服务去搭建一套Dubbo环境以及编写消费端代码。服务测试的详细使用方式可通过点击这里进行了解。
  
  添加 SessionController 用于用户登录,内容如下:
  
  using System.ComponentModel.DataAnnotations;
  
  using System.Net.Http;
  
  using System.Threading.Tasks;
  
  using IdentityModel.Client;
  
  using Microsoft.AspNetCore.Mvc;
  
  namespace ServiceA.Controllers
  
  {
  
  [Route("api/[controller]")]
  
  [ApiController]
  
  public class SessionController : ControllerBase
  
  {
  
  public async Task<string> Login(UserRequestModel userRequestModel)
  
  {
  
  // discover endpoints from metadata
  
  var client = new HttpClient();
  
  DiscoveryResponse disco = await client.GetDiscoveryDocumentAsync("http://127.0.0.1:8021");
  
  if (disco.IsError)
  
  {
  
  return "认证服务器未启动";
  
  }
  
  TokenResponse tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
  
  {
  
  Address = disco.TokenEndpoint,
  
  ClientId = "ServiceAClient",
  
  ClientSecret =dasheng178.com "ServiceAClient",
  
  UserName = userRequestModel.Name,
  
  Password = userRequestModel.Password
  
  });
  
  return tokenResponse.IsError ? tokenResponse.Error : tokenResponse.AccessToken;
  
  }
  
  }
  
  public class UserRequestModel
  
  {
  
  [Required(ErrorMessage = "用户名称不可以为空")]
  
  public string Name {www.078886.cn get; set; }
  
  [Required(ErrorMessage = "用户密码不可以为空")]
  
  public string Password { get; set; }
  
  }
  
  }
  
  添加 HealthController 用于 Consul 进行服务健康检查,内容如下:
  
  using Microsoft.AspNetCore.Mvc;
  
  namespace ServiceA.Controllers
  
  {
  
  [Route("api/[controller]"), ApiController]
  
  public class HealthController : ControllerBase
  
  {
  
  /// <summary>
  
  /// 健康检查
  
  /// </summary>
  
  /// <returns>www.yongshiyule178.com</returns>
  
  [HttpGet]
  
  public IActionResult Get()
  
  {
  
  return Ok();
  
  }
  
  }
  
  }
  
  更改 ValuesController.cs 内容如下:
  
  using System.Collections.Generic;
  
  using Microsoft.AspNetCore.Authorization;
  
  using Microsoft.AspNetCore.Mvc;
  
  namespace ServiceA.Controllers
  
  {
  
  [Authorize] //添加 Authorize Attribute 以使该控制器启用认证
  
  [Route("api/[controller]")]
  
  [ApiController]
  
  public class ValuesController : ControllerBase
  
  {
  
  // GET api/values
  
  [HttpGet]
  
  public ActionResult<IEnumerable<string>> Get()
  
  {
  
  return new[] { "value1", "value2" };
  
  }
  
  }
  
  }
  
  注意,以上基本完成了 ServiceA 的服务构建,但在实际应用中应做一些修改,例如:IdentityServer 地址应在 appsettings.json 中进行配置,不应把地址分散于项目中各处;认证服务启用最好在全局启用,以防止漏写等等。ServiceB 的内容与 ServiceA 大致相似,因此文章中将不再展示 ServiceB 的构建过程。
  
  Gateway 构建
  
  添加ASP.Net Web
  
  添加空项目
  
  打开程序包管理器控制台输入命令:
  
  csharp install-package Ocelot //添加 Ocelot
  
  csharp install-package Ocelot.Provider.Consul // 添加 Consul 服务发现
  
  添加 ocelot.json 文件,内容如下
  
  {
  
  "ReRoutes": [
  
  {
  
  "DownstreamPathTemplate": "/api/{everything}",
  
  "DownstreamScheme": "http",
  
  "UpstreamPathTemplate": "/ServiceA/{everything}",
  
  "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
  
  "ServiceName": "ServiceA", //consul 服务中 ServiceA 的名称
  
  "LoadBalancerOptions": {
  
  "Type": "LeastConnection"
  
  }
  
  },
  
  {
  
  "DownstreamPathTemplate": "/api/{everything}",
  
  "DownstreamScheme": "http",
  
  "UpstreamPathTemplate": "/ServiceB/{everything}",
  
  "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
  
  "ServiceName": "ServiceB", //consul 服务中 ServiceB 的名称
  
  "LoadBalancerOptions": {
  
  "Type": "LeastConnection"
  
  }
  
  }
  
  ],
  
  "GlobalConfiguration": {
  
  "ServiceDiscoveryProvider": { // Consul 服务发现配置
  
  "Host": "localhost", // Consul 地址
  
  "Port": 8500,
  
  "Type": "Consul"
  
  }
  
  }
  
  }
  
  删除 StartUp.cs 文件,在 Program.cs 文件中添加如下内容
  
  using System.IO;
  
  using Microsoft.AspNetCore.Hosting;
  
  using Microsoft.Extensions.Configuration;
  
  using Ocelot.DependencyInjection;
  
  using Ocelot.Middleware;
  
  using Ocelot.Provider.Consul;
  
  namespace ApiGateway
  
  {
  
  public class Program
  
  {
  
  public static void Main(string[] args)
  
  {
  
  new WebHostBuilder()
  
  .UseKestrel()
  
  .UseContentRoot(Directory.GetCurrentDirectory())
  
  .ConfigureAppConfiguration((hostingContext, config) =>
  
  {
  
  config
  
  .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
  
  .AddJsonFile("appsettings.json", true, true)
  
  .AddJsonFile($"appsettings.www.ouyi3pt1.cn{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
  
  .AddJsonFile(www.dituyule.org"ocelot.json")
  
  .AddEnvironmentVariables(www.yingxionghui1.cn);
  
  })
  
  .ConfigureServices(services =>
  
  {
  
  services.AddOcelot().AddConsul();
  
  })
  
  .ConfigureLogging((hostingContext, logging) =>
  
  {
  
  //add your logging
  
  })
  
  .UseIISIntegration()
  
  .Configure(app =>
  
  {
  
  app.UseOcelot().Wait();
  
  })
  
  .Build()
  
  .Run();
  
  }
  
  }
  
  }
  
  注意:打开 Gateway.csproj 文件,更改
  
  <PropertyGroup>
  
  <TargetFramework>netcoreapp2.2</TargetFramework>
  
  <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  
  </PropertyGroup>
  
  为
  
  <PropertyGroup>
  
  <TargetFramework>netcoreapp2.2</TargetFramework>
  
  <AspNetCoreHostingModel>www.fengshen157.com/ OutOfProcess</AspNetCoreHostingModel>
  
  </PropertyGroup>
  
  至此,一个基础网关基本构建完成。
  
  构建 Consul 服务
  
  使用 Chocoletey 安装 Consul,
  
  choco install consul
  
  新建一个文件夹以保存 Consul 服务配置
  
  在 consul.d 文件夹中添加配置文件,内容如下:
  
  {
  
  "services": [{
  
  "ID": "ServiceA",
  
  "Name": "ServiceA",
  
  "Tags": [
  
  "ServiceAWebApi", "Api"
  
  ],
  
  "Address": "127.0.0.1",
  
  "Port": 8010,
  
  "Check": {
  
  "HTTP": "http://127.0.0.1:8010/Api/health",
  
  "Interval": "10s"
  
  }
  
  }, {
  
  "id": "ServiceB",
  
  "name": "ServiceB",
  
  "tags": [
  
  "ServiceBWebApi","Api"
  
  ],
  
  "Address": "127.0.0.1",
  
  "Port": 8011,
  
  "Check": [{
  
  "HTTP": "http://127.0.0.1:8011/Api/health",
  
  "Interval": "10s"
  
  }
  
  ]
  
  }
  
  ]
  
  }
  
  启动 consul 服务
  
  consul agent -dev -config-dir=./consul.d
  
  启动后在浏览器中输入 http://localhost:8500/ui/ 以查看Consul服务
  
  Postman 验证
  
  F5 启动 Gateway 项目,启动 Postman 发送请求到 ServiceA 获取 Token。
  
  使用 Token 请求 ServiceA Values 接口
  
  当尝试使用 ServiceA 获取到的 Token 去获取 ServiceB 的数据时,请求也如意料之中返回 401
  
  总结
  
  至此,一个由 .NET Core、IdentityServer4、Ocelot、Consul实现的基础架构搭建完毕。源码地址

Dubbo 生态添新兵,Dubbo Admin 发布 v0.1的更多相关文章

  1. dubbo源码之四——dubbo服务发布

    dubbo版本:2.5.4 服务发布是服务提供方向注册中心注册服务过程,以便服务消费者从注册中心查阅并调用服务. 服务发布方在spring的配置文件中配置如下: <bean id="d ...

  2. dubbo 源码学习1 服务发布机制

    1.源码版本:2.6.1 源码demo中采用的是xml式的发布方式,在dubbo的 DubboNamespaceHandler 中定义了Spring Framework 的扩展标签,即 <dub ...

  3. Dubbo 系列(05-1)服务发布

    目录 Dubbo 系列(05-1)服务发布 Spring Cloud Alibaba 系列目录 - Dubbo 篇 1. 背景介绍 1.1 服务暴露整体机制 2. 源码分析 2.1 前置工作 2.2 ...

  4. Spring Cloud Alibaba生态探索:Dubbo、Nacos及Sentinel的完美结合

    @ 目录 背景 一.项目框架 1.1 采用IDEA和Maven多模块进行项目搭建 1.2 模块管理及版本管理 二.微服务公共接口 2.1 定义一个公共接口Api 2.2 pom.xml 2.3 Goo ...

  5. dubbo系列五、dubbo核心配置

    一.配置文件 1.生产者配置provider.xml <?xml version="1.0" encoding="UTF-8"?> <bean ...

  6. dubbo系列四、dubbo服务暴露过程源码解析

    一.代码准备 1.示例代码 参考dubbo系列二.dubbo+zookeeper+dubboadmin分布式服务框架搭建(windows平台) 2.简单了解下spring自定义标签 https://w ...

  7. dubbo系列二、dubbo+zookeeper+dubboadmin分布式服务框架搭建(windows平台)

    一.zookeeper配置中心安装 1.下载安装包,zookeeper-3.4.6.tar.gz 2.解压安装包,修改配置文件 参考zookeeper-3.4.6/conf/zoo_sample.cf ...

  8. dubbo入门学习(二)-----dubbo hello world

    一.dubbo hello world入门示例 1.提出需求 某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址: 我们现在需要创建两个服务模块进行测试: 模块 功能 订单服务web模块 创 ...

  9. dubbo系列一、dubbo启动流程

    目录 dubbo启动流程分析记录 一.dubbo provider启动流程 1.自动装配 2.ServiceBean处理 3.服务暴露export() 3.1.检测dubbo.xxx.配置属性,配置到 ...

随机推荐

  1. 百度谷歌雅虎三大搜索引擎比较和如何配置谷歌访问助手访问Google搜索服务

    引言: 由于近期网上盛传”百度搜索引擎已死“的消息,引发个人对于搜索引擎的思考.百度作为最大的中文搜索引擎,确实有着很大声誉,再加上本地化的优势,正成为国人们的首选,但是作为一名技术开发人员,使用搜索 ...

  2. 20155211 网络对抗 Exp9 Web安全基础实践

    20155211 网络对抗 Exp9 Web安全基础实践 基础问题回答 SQL注入攻击原理,如何防御? 原理:SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语 ...

  3. POJ1035&&POJ3080&&POJ1936

    字符串处理专题,很早就写好了然而忘记写blog了 1035 题意:给你一些单词作为字典.然后让你查找一些单词.对于每个单词,如果在字典中就输出它.否则输出所有它通过删除||增加||替换一个字符能得到的 ...

  4. LoRa---她的简介和她的专业术语

    LoRa是LPWAN(低功耗广域网)通信技术的一种,其作用距离超过 15 公里,连接节点可达 100 万个.低功耗与长距离极限的组合可将最大数据速率提升至每秒 50千比特(Kbps). LoRa 是  ...

  5. JavaScript快速入门-ECMAScript本地对象(String)

    一.String对象 String对象和python中的字符串一样,也有很多方法,这些方法大概分为以下种类: 1.索引和查找 1.charAt()   返回指定位置的字符. 2.charCodeAt( ...

  6. Spring+SpringMVC+MyBatis整合基础篇

    基础篇 Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介 Spring+SpringMVC+MyBatis+easyUI整合基础篇(二)牛刀小试 Spring+S ...

  7. C语言中指针占据内存空间问题

    以前一直有个疑问,指向不同类型的指针到底占用的内存空间是多大呢? 这个问题我多次问过老师,老师的答案是"指向不同类型的指针占据的内存空间大小不同",我一直很之一这个答案,今天我就做 ...

  8. python3面向对象注意事项

    一.面向对象super的作用: class parent(object): def __init__(self): self.test() def test(self): print('parent- ...

  9. ngnix的基本安装及配置 centos7

    1.centos7  挂载ngnix的源 rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7- ...

  10. Keras学习笔记。

    1. keras.layers.Dense (Fully Connected Neural NetWork),所实现的运算是output = activation(dot(input, kernel) ...