本系列编写目的纯属个人开发记录  以下代码均为demo级 如有需要 请自行优化 代码完整包由于公司电脑加密 无法上传整包的demo文件

consul 开发环境简易处理

consul 下载地址 : https://www.consul.io/downloads.html

此处使用windows 64版本

为方便使用在创建一个bat文件 命令如下:

cd C:\Users\Lenovo\Desktop\    
consul.exe agent -dev

第一行为进入桌面

第二行为 执行consul开发模式

运行后可在 localhost:8500 地址处看到consul 后台服务管理页面

搭建测试API

由于 使用了consul 最新nuget包 所以 在创建的时候需要使用 .netcore 2.1

由于已经搭建了demo1 这里演示截图会是demo2 创建方式一样

创建一个core 2.1的API空项目

创建一个BaseController 用来保存配置信息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; namespace DemoApi_I.Controllers
{
public class BaseController : ControllerBase
{
public static Setting Config;
public BaseController(IOptions<Setting> setting)
{
Config = setting.Value;
}
}
}

BaseController

再添加一个健康检查的控制器

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; namespace DemoApi_II.Controllers
{
[Route("api/[controller]")]
public class HealthController : BaseController
{
public HealthController(IOptions<Setting> setting) : base(setting)
{
} // GET api/values
[HttpGet]
public string Get()
{
return "ok";
}
}
}

HealthController.cs

为了统一显示 可以更改默认values控制器为

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; namespace DemoApi_II.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : BaseController
{
public ValuesController(IOptions<Setting> setting) : base(setting)
{
}
// GET api/values
[HttpGet]
public string Get()
{
var aaa = Config.ServiceName;
return "二号测试API";
}
}
}

ValuesController

接下来 增加 一个配置类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; namespace DemoApi_II
{
public class Setting
{
/// <summary>
/// 端口号
/// </summary>
public int Port { get; set; }
/// <summary>
/// 服务名称
/// </summary>
public string ServiceName { get; set; }
/// <summary>
/// 服务发现IP
/// </summary>
public string ConsulIP { get; set; }
/// <summary>
/// 服务发现端口号
/// </summary>
public int ConsulPort { get; set; } }
}

Setting.cs

在appsettings.json 内新增节点

测试地址中只需要改端口号和服务名称即可 会自动读取本机ip到注入到consul中

 "Setting": {
"Port": "",
"ServiceName": "demoAPi",
"ConsulIP": "localhost",
"ConsulPort": ""
}

新增部分

注意 需要修改为 始终复制或者较新复制

修改 Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; namespace DemoApi_II
{
public class Program
{
public static string StartPort;
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true)
.Build();
StartPort = config.GetSection("Setting")["Port"];
CreateWebHostBuilder(args).Build().Run();
} public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls($"http://*:{StartPort}")
.UseStartup<Startup>();
}
}

Program.cs

修改startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ConsulRegisterHelper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; namespace DemoApi_II
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<Setting>(Configuration.GetSection("Setting"));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.RegisterConsul(lifetime, new ServiceEntity
{
IP = NetworkHelper.LocalIPAddress,
Port = Convert.ToInt32(Configuration.GetSection("Setting")["Port"]),
ServiceName = Configuration.GetSection("Setting")["ServiceName"],
ConsulIP = Configuration.GetSection("Setting")["ConsulIP"],
ConsulPort = Convert.ToInt32(Configuration.GetSection("Setting")["ConsulPort"])
});
}
}
}

Startup.cs

创建自动注入consul服务的类库

新建core2.1类库项目 取名ConsulRegisterHelper

将以下3个类创建即可

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets; namespace ConsulRegisterHelper
{
public class NetworkHelper
{
public static string LocalIPAddress
{
get
{
UnicastIPAddressInformation mostSuitableIp = null;
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (var network in networkInterfaces)
{
if (network.OperationalStatus != OperationalStatus.Up)
continue;
var properties = network.GetIPProperties();
if (properties.GatewayAddresses.Count == )
continue; foreach (var address in properties.UnicastAddresses)
{
if (address.Address.AddressFamily != AddressFamily.InterNetwork)
continue;
if (IPAddress.IsLoopback(address.Address))
continue;
return address.Address.ToString();
}
} return mostSuitableIp != null
? mostSuitableIp.Address.ToString()
: "";
}
} public static int GetRandomAvaliablePort(int minPort = , int maxPort = )
{
Random rand = new Random();
while (true)
{
int port = rand.Next(minPort, maxPort);
if (!IsPortInUsed(port))
{
return port;
}
}
} private static bool IsPortInUsed(int port)
{
IPGlobalProperties ipGlobalProps = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] ipsTCP = ipGlobalProps.GetActiveTcpListeners(); if (ipsTCP.Any(p => p.Port == port))
{
return true;
} IPEndPoint[] ipsUDP = ipGlobalProps.GetActiveUdpListeners();
if (ipsUDP.Any(p => p.Port == port))
{
return true;
} TcpConnectionInformation[] tcpConnInfos = ipGlobalProps.GetActiveTcpConnections();
if (tcpConnInfos.Any(conn => conn.LocalEndPoint.Port == port))
{
return true;
} return false;
}
}
}

NetworkHelper.cs

using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using System; namespace ConsulRegisterHelper
{
public static class AppBuilderExtensions
{
public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, ServiceEntity serviceEntity)
{
var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{serviceEntity.ConsulIP}:{serviceEntity.ConsulPort}"));//请求注册的 Consul 地址
var httpCheck = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(),//服务启动多久后注册
Interval = TimeSpan.FromSeconds(),//健康检查时间间隔,或者称为心跳间隔
HTTP = $"http://{serviceEntity.IP}:{serviceEntity.Port}{serviceEntity.HealthUrl}",//健康检查地址
Timeout = TimeSpan.FromSeconds()
}; // Register service with consul
var registration = new AgentServiceRegistration()
{
Checks = new[] { httpCheck },
ID = Guid.NewGuid().ToString(),
Name = serviceEntity.ServiceName,
Address = serviceEntity.IP,
Port = serviceEntity.Port,
Tags = new[] { $"urlprefix-/{serviceEntity.ServiceName}" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
}; consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)
lifetime.ApplicationStopping.Register(() =>
{
consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册
}); return app;
}
}
}

Register.cs

using System;
using System.Collections.Generic;
using System.Text; namespace ConsulRegisterHelper
{
public class ServiceEntity
{
public ServiceEntity()
{
HealthUrl = "/api/health";
}
/// <summary>
/// 服务IP
/// </summary>
public string IP { get; set; }
/// <summary>
/// 服务端口号
/// </summary>
public int Port { get; set; }
/// <summary>
/// 服务名称
/// </summary>
public string ServiceName { get; set; }
/// <summary>
/// 服务发现地址
/// </summary>
public string ConsulIP { get; set; }
/// <summary>
/// 服务发现端口号
/// </summary>
public int ConsulPort { get; set; }
/// <summary>
/// 健康检查地址默认为/api/health
/// </summary>
public string HealthUrl { get; set; }
}
}

ServiceEntity.cs

在需要注入的服务Startup.cs中通过如下代码注入:

创建bat文件方便测试使用

E:
cd E:\ServerApi\OcelotGetWay\DemoApi_II\bin\Debug\netcoreapp2.
dotnet DemoApi_II.dll

实例代码

到此 测试demoapi 准备完成

参考内容:

微服务系列文章

https://www.cnblogs.com/edisonchou/p/dotnetcore_microservice_foundation_blogs_index_final.html

ocelot配置特性介绍

https://blog.csdn.net/qin_yu_2010/article/details/82749414

微服务网关从零搭建——(一)创建测试api以及api自动注入consul的更多相关文章

  1. 微服务网关从零搭建——(三)Ocelot网关 + identity4

    增加验证服务 1.创建名为AuthService 的core 空项目 2.修改startup文件 using System; using System.Collections.Generic; usi ...

  2. 微服务网关从零搭建——(二)搭建api网关(不带验证)

    环境准备 创建空的core2.1 api项目  演示使用名称APIGateWay  过程参考上一篇 完成后在appsettings.json 添加节点 "Setting": { & ...

  3. 微服务网关从零搭建——(七)更改存储方式为oracle

    资源准备: 下载开源项目 新建oracle表: -- ---------------------------- -- Table structure for OcelotGlobalConfigura ...

  4. 微服务网关从零搭建——(九)网关部署到linux服务器

    环境准备 公司电脑已安装core环境所以此处略过core环境安装 可参看此处 consul安装 如果没有wget命令 执行以下命令 yum install wget 下载consul wget htt ...

  5. 微服务网关从零搭建——(八)Ocelot网关中加入skywalking APM

    准备工作 一.下载skywalking 本例使用的是 注: 1.解压后执行完2,3步骤后运行\bin\startup.bat 2.默认后台端口为8080 如需修改则修改\webapp\webapp.y ...

  6. 微服务网关从零搭建——(六)ocelot配置追踪功能

    butterfly 准备工作 首先下载buterfly release版本 解压并通过命令启动:dotnet Butterfly.Web.dll --EnableHttpCollector=true ...

  7. 小D课堂 - 新版本微服务springcloud+Docker教程_6-06 zuul微服务网关集群搭建

    笔记 6.Zuul微服务网关集群搭建     简介:微服务网关Zull集群搭建 1.nginx+lvs+keepalive      https://www.cnblogs.com/liuyisai/ ...

  8. 微服务之:从零搭建ocelot网关和consul集群

    介绍 微服务中有关键的几项技术,其中网关和服务服务发现,服务注册相辅相成. 首先解释几个本次教程中需要的术语 网关 Gateway(API GW / API 网关),顾名思义,是企业 IT 在系统边界 ...

  9. Spring Cloud微服务安全实战_4-1_微服务网关安全_概述&微服务安全面临的挑战

      第四章  网关安全 这一章从简单的API的场景过渡到复杂的微服务的场景 4.1 概述 微服务安全面临的挑战:介绍中小企业的一个微服务架构,相比第三章的单体应用的简单的API所面临的哪些挑战 OAu ...

随机推荐

  1. 阳性比例 mysql CASE UNION ALL

    阳性比例 mysql CASE UNION ALL SELECT t.*,t.type_0/all_ FROM ( SELECT FROM_UNIXTIME(create_time,'%Y-%m-%d ...

  2. vim升级到8.0

    1.卸载 sudo apt-get remove --purge vim 2.添加8.0的vim源并安装 sudo add-apt-repository ppa:jonathonf/vim sudo ...

  3. Opencv+Zbar二维码识别(一维码校正)

    一维码由一组规则排列的黑色线条.白色线条以及对应的字符组成.对倾斜的(没有严重形变)一维码的角度校正,可以根据其黑白相间.排列规则的特点,计算傅里叶频谱,通过傅里叶频谱中直线的倾斜角度计算空间域图像一 ...

  4. 解决Error for wireless request "Set Mode" (8B06) 问题 (转载)

    转自:http://blog.csdn.net/muge0913/article/details/17062871 在运行以下命令的时候,意外的出错,最后google了下,最终才确定了原因,因为在运行 ...

  5. bzoj 1093: [ZJOI2007]最大半连通子图【tarjan+拓扑排序+dp】

    先tarjan缩成DAG,然后答案就变成了最长链,dp的同时计数即可 就是题面太唬人了,没反应过来 #include<iostream> #include<cstdio> #i ...

  6. 17年day2

    /* 嗯,明天就出发了. 嗯,终于快要结束了. 考试日常挂T1 今天晚上老师们请我们吃水饺,还有一个大蛋糕. 虽然没怎么吃蛋糕23333 还好我的水饺是白菜馅的~~~ 晚上学哥学姐们发视频送祝福,谢谢 ...

  7. VBScript+SCR+NetApi+Accoreconsole 批处理dwg文件

    继上次powershell运行accoreconsole(https://www.cnblogs.com/NanShengBlogs/p/10981687.html)的研究之后又觉得不是很合适,毕竟p ...

  8. SpringCloud(Finchley版本)中Zull过滤器ResponseBoby返回中文乱码解决方案

    Spring Cloud带有"Cloud"的字样,但它并不是云计算解决方案,而是在Spring Boot基础上构建的,用于快速构建分布式系统的通用模式的工具集.使用Spring C ...

  9. navicat mysql报错误:2013 Lost connection to MySQL server during query

    好像是MySQL的navicat UI界面跟数据的连接问题,如果直接用命令导入数据的话,或许能规避这个问题.

  10. EditText(7)EditText输入事件监听

    EditText.addTextChangedListener(TextWatcher watcher); void initSearch(){ search = (EditText) findVie ...