Undertow Undertow 是红帽公司开发的一款基于 NIO 的高性能 Web 嵌入式服务器 Untertow 的特点: 轻量级:它是一个 Web 服务器,但不像传统的 Web 服务器有容器概念,它由两个核心 Jar 包组成,加载一个 Web 应用可以小于 10MB 内存 Servlet3.1 支持:它提供了对 Servlet3.1 的支持 WebSocket 支持:对 Web Socket 完全支持,用以满足 Web 应用巨大数量的客户端 嵌套性:它不需要容器,只需通过 API 即可快速搭建 Web 服务器 默认情况下 Spring Cloud 使用 Tomcat 作为内嵌 Servlet 容器,可启动一个 Tomcat 的 Spring Boot 程序与一个 Undertow 的 Spring Boot 程序,通过 VisualVM 工具进行比较,可看到 Undertow 性能优于 Tomcat 使用 Undertow 添加依赖
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> |
支持 HTTP2
|
1 2 3 4 5 6 7 8 9 10 11 |
// 在@Configuration的类中添加@bean @Bean UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() { UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory(); // 这里也可以做其他配置 factory.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true)); return factory; } |
配置 Undertow
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# Undertow 日志存放目录 server.undertow.accesslog.dir # 是否启动日志 server.undertow.accesslog.enabled=false # 日志格式 server.undertow.accesslog.pattern=common # 日志文件名前缀 server.undertow.accesslog.prefix=access_log # 日志文件名后缀 server.undertow.accesslog.suffix=log # HTTP POST请求最大的大小 server.undertow.max-http-post-size=0 # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 server.undertow.io-threads=4 # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载 server.undertow.worker-threads=20 # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 # 每块buffer的空间大小,越小的空间被利用越充分 server.undertow.buffer-size=1024 # 每个区分配的buffer数量 , 所以pool的大小是buffer-size * buffers-per-region server.undertow.buffers-per-region=1024 # 是否分配的直接内存 server.undertow.direct-buffers=true |
from:https://www.jianshu.com/p/e625b8aa0e80
View Detailsflyray项目介绍 使用Spring+SpringMVC+Mybatis+dubbox 开发的一套分布式基础框架,提供支付、对账、清结算、客户管理、营销活动、库存管理、搜索模块、rocketmq做统一的消息队列中心 飞雷开源平台 cms前端工程 开发手册 开发部署文档 接口文档文档 各模块功能文档 有兴趣、想学习部署的可以加群交流 使用技术 后台 Maven构建项目 Jenkins作为持续集成 安全框架:Apache Shiro 1.3 构上采用Dubbox作为RPC框架 使用Spring+Spring MVC+MyBatisSSM框架 数据库连接池使用druid 数据库使用MySQL和Redis 采用elasticsearch实现搜索服务 采用quartz做任务调度 注册中心ZooKeeper 消息中间件RocketMQ, 在分布式事务上则采用了TCC解决订单支付方面时效性要求性高的分布式事务,可靠的消息服务则来解决如会计记录等时效性要求低的分布式事务. 前台 页面交互Vue2.x 数据可视化echarts 项目进度 组织结构 接口总线系统 对外暴露统一规范的接口,包括各个子系统的交互接口示例图: 运营中心 商户中心 开放平台 ##运行流程 ##flyray-base 项目搭建 系统环境:windows10 jdk8 eclipse tomcat8 ##搭建步骤 安装jdk1.8 安装maven 安装zookeeper 下载项目:git clone https://git.oschina.net/boleixiongdi/flyray.git eclipse导入maven项目 在群里下载缺少的dubbox包和zkclient包 解决缺少其他jar包问题,直到项目不报错 ##导入后项目结构 ##项目架构图 ##项目启动步骤 导入数据库脚本 flyray-os-各模块总的数据库.sql flyray-security-三个中心的数据库.sql 修改config工程中的resource下的dubbo、数据库配置文件 修改 flyray-rbac 下的flyray-merchant-web、flyray-open-web、flyray-operation-web中的resource\service-consumer.xml文件的dubbo IP 启动注册中心即zookeeper 启动所有的服务提供者cms、crm、pay、erp下的web工程 启动rest,rest既是cms、crm、pay、erp的服务消费者又是merchant-web、open-web、operation-web的服务提供者 最后启动merchant-web可以登录商户中心、启动operation-web可以登录运营中心、启动open-web可以看到开放平台 from:https://gitee.com/boleixiongdi/flyray
View Details今天闲来无事,学习Zookeeper,下载了Zookeeper的最新版本3.5。启动以后显示: 1 2 3 ZooKeeper JMX enabled by default Using config: /opt/zookeeper-3.5.4-beta/bin/../conf/zoo.cfg Starting zookeeper … STARTED 以为启动成功,然后连接时报错,查看后台进程,没有Zookeeper进程。 查看zookeeper的日志文件: 1 2 2018-06-29 01:36:01,142 [myid:] – ERROR [main:ZooKeeperServerMain@79] – Unable to start AdminServer, exiting abnormally org.apache.zookeeper.server.admin.AdminServer$AdminServerException: Problem starting AdminServer on address 0.0.0.0, port 8080 and command URL /commands 发现8080端口被占用,通过查阅Zookeeper3.5的官方文档,发现这是Zookeeper3.5的新特性: 这是Zookeeper AdminServer,默认使用8080端口,它的配置属性如下: 我们可以修改在zoo.cfg中修改AdminServer的端口: 1 admin.serverPort=8888 保存后,再次启动,Zookeeper启动成功。 from:https://www.cnblogs.com/boboooo/p/9242088.html
View Detailszookeeper安装教程(zookeeper3.4.8为例) zookeeper有单机、伪集群、集群三种部署方式,可根据自己对可靠性的需求选择合适的部署方式。下边是单机部署的介绍。 一、单机安装 1.1 下载 进入要下载的版本的目录,选择.tar.gz文件下载,具体需要哪个版本,这个由你自己选择 下载链接:http://archive.apache.org/dist/zookeeper/ 1.2 配置,下载解压得到如下图所示: 点击conf,把zoo_sample.cfg修改成zoo.cfg,必须是叫这个名称。然后对其进行修改。 用文本打开zoo.cfg具体修改如下: 1.3,启动zooker服务。启动命令在bin文件下的zkServer.cmd. 当看到这个2181就表示启动成功了。 对于zookeeper集群,其实也就是修改conf/zoo.cfg的dataDir的存放位置以及相应在端口号,如第一个端口号:2181,第二个3181,…依次类推。这里不做详细介绍。 检查是否安装成功方式二:运行cmd,在命令行中输入jps如下图所示,表示zookeeper安装启动成功了。 到此,单机的zookeeper布置就结束。 那么,就可以搭建dubbo了。记得在搭建前先把zookeeper启动!!! from:https://blog.csdn.net/qq_30764991/article/details/80188652
View Details症状:验证码上只有背景图没有文字 Warning: imagettftext() [function.imagettftext]: Could not find/open font in ***.php on line ** 解决方案:处理掉中文目录!! 网上搜索到的答案大多是字体文件目录不对或者相对或绝对路径方面的问题,写下这段文字给后面需要填坑的朋友。 from:https://xiumu.org/note/php-imagettftext-could-not-find-open-the-font-errors.shtml
View Detailsmaven依赖的项目报错Could not resolve dependencies for project问题 maven如果依赖本地项目 1.例如自己本地项目是模块化的 首先将报错的模块执行 clean 和package 2. 然后执行install,将上一步执行成功的jar文件安装到responsitory 3.最后执行 mvn clean install -Dmaven.test.skip=true from:https://blog.csdn.net/zgy_boke/article/details/85243453
View Detailshttp://www.bubuko.com/infodetail-2130667.html 使用maven创建子工程时,子工程需要依赖父工程,创建以后报错Project build error: Non-resolvable parent POM: Failure to find…… 网上的答案绝大多数都是在<parent></parent>中间加一行:<relativePath>../../pom.xml</relativePath>(原因是找不到路径) 但是我加了依旧没有解决,我的解决方法是,在子项目名点击右键--> run as -->maven install。待自动下载完包后就便可以解决错误 from:https://blog.csdn.net/baidu_18607183/article/details/80479925
View Details在本部分中,将修改 HelloWorldController 类,进而使用 Razor 视图文件来顺利封装为客户端生成 HTML 响应的过程。 使用 Razor 创建视图模板文件。 当前,Index 方法返回带有在控制器类中硬编码的消息的字符串。 C#
|
1 2 3 4 |
public IActionResult Index() { return View(); } |
上面的代码调用控制器的 View 方法。 添加视图 Visual Studio Visual Studio Code Visual Studio for Mac 右键单击“视图”文件夹,然后单击“添加”>“新文件夹”,并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹,然后单击“添加”>“新项”。 在“添加新项 – MvcMovie”对话框中 在右上角的搜索框中,输入“视图” 选择“Razor 视图” 保持“名称”框的值:Index.cshtml 。 选择“添加” 为 HelloWorldController 添加 Index 视图。 添加一个名为“Views/HelloWorld”的新文件夹。 向 Views/HelloWorld 文件夹添加名为“Index.cshtml”的新文件。 右键单击“视图”文件夹,然后单击“添加”>“新文件夹”,并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹,然后单击“添加”>“新文件” 。 在“新建文件”对话框中 : 在左窗格中,选择“Web” 。 在中间窗格中,选择“空 HTML 文件” 。 在“名称”框中键入“Index.cshtml” 。 选择“新建” 。 使用以下内容替换 Razor 视图文件 Views/HelloWorld/Index.cshtml 的内容 : HTML
|
1 |
@{ ViewData["Title"] = "Index"; } <h2>Index</h2> <p>Hello from our View Template!</p> |
导航到 https://localhost:{PORT}/HelloWorld。 更改视图和布局页面 选择菜单链接(“MvcMovie”、“首页”和“隐私”) 。 布局模板使你能够在一个位置指定网站的 HTML 容器布局,然后将它应用到网站中的多个页面。 更改布局文件中的标题、页脚和菜单链接 在标题和页脚元素中,将 MvcMovie 更改为 Movie App。 将定位点元素 <a […]
View Details众所周知,在asp.net core中编写Razor视图的时候,用了一种新的写法--TagHelper 那这个TagHelper是怎么回事呢? 首先来看看TagHelper的项目位置,它是位于Microsoft.AspNetCore.Mvc.TagHelpers。 如果看到project.json,可以发现,它还依赖一个比较重要的东西Microsoft.AspNetCore.Mvc.Razor 为什么这么说呢,其实很简单,看了里面诸多TagHelper,就会发现,里面都是继承了 Microsoft.AspNetCore.Razor.TagHelpers下面的TagHelper这个抽象类。 下面就以我们天天用到的表单--FormTagHelper为例来说一下,他是怎么实现的。 首先要看看TagHelper这个抽象类:
|
1 2 3 4 5 6 7 8 |
public abstract class TagHelper : ITagHelper { protected TagHelper(); public virtual int Order { get; } public virtual void Init(TagHelperContext context); public virtual void Process(TagHelperContext context, TagHelperOutput output); public virtual Task ProcessAsync(TagHelperContext context, TagHelperOutput output); } |
里面包含两比较重要的方法:Process和ProcessAsync 其实看方法名就应该知道一个是同步的方法一个是异步的方法 因为这个是输出html的方法,你说,这能不重要吗?下面来看看FormTagHelper的具体实现吧!
|
1 |
[HtmlTargetElement("form", Attributes = ActionAttributeName)] |
先来看看HtmlTargetElement这个Attribute是用来干嘛的 简单来说,它指定了我们html标签(<form></form>)以及一些相关的元素。 可以看到,诸多Attributes = XXXAttributeName,其中的XXXAttributeName是在类里面定义的变量。
|
1 2 3 4 5 6 7 8 |
private const string ActionAttributeName = "asp-action"; private const string AntiforgeryAttributeName = "asp-antiforgery"; private const string AreaAttributeName = "asp-area"; private const string ControllerAttributeName = "asp-controller"; private const string RouteAttributeName = "asp-route"; private const string RouteValuesDictionaryName = "asp-all-route-data"; private const string RouteValuesPrefix = "asp-route-"; private const string HtmlActionAttributeName = "action"; |
再来看看下面的图,相对比一看,是不是就很清晰了呢? 我们可以看到下面的好几个属性,如Controller,它的上面是有 HtmlAttributeName来标注的 而且这个指向的名字还是ControllerAttributeName(也就是asp-controller)。这个就是用来接收asp-controller的值。
|
1 2 |
[HtmlAttributeName(ControllerAttributeName)] public string Controller { get; set; } |
相对来说,这样做只是起了个别名。
|
1 2 3 4 5 6 7 8 |
[HtmlTargetElement("form", Attributes = ActionAttributeName)] [HtmlTargetElement("form", Attributes = AntiforgeryAttributeName)] [HtmlTargetElement("form", Attributes = AreaAttributeName)] [HtmlTargetElement("form", Attributes = ControllerAttributeName)] [HtmlTargetElement("form", Attributes = RouteAttributeName)] [HtmlTargetElement("form", Attributes = RouteValuesDictionaryName)] [HtmlTargetElement("form", Attributes = RouteValuesPrefix + "*")] public class FormTagHelper : TagHelper |
当然,我们也是可以不指定别名的,也可以不用在HtmlTargetElement指明Attributes 好比如下的代码,就可以直接用Controller
|
1 2 3 4 5 |
[HtmlTargetElement("form")] public class FormTagHelper : TagHelper { public string Controller { get; set; } } |
还有一个RouteValues的属性,它是一个键值对,用来存放参数的,具体可以怎么用呢? 总的来说有两种用法。可以看到它指向asp-all-route-data和asp-route-
|
1 |
[HtmlAttributeName(RouteValuesDictionaryName, DictionaryAttributePrefix = RouteValuesPrefix)] |
用法如下:一种是用asp-all-route-data来接收一个IDictionary类型的变量,一种是通过asp-route-*的方式来接收参数*的值。 这两种写法是等价的。 下面就是FormTagHelper的构造函数和一个Generator属性
|
1 2 3 4 5 |
public FormTagHelper(IHtmlGenerator generator) { Generator = generator; } protected IHtmlGenerator Generator { get; } |
由于在Core中,依赖注入随处可见,看到这个写法马上就是想到了这个 果不其然,发现其对应了一个实现类:DefaultHtmlGenerator。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class DefaultHtmlGenerator : IHtmlGenerator { public DefaultHtmlGenerator(IAntiforgery antiforgery, IOptions<MvcViewOptions> optionsAccessor, IModelMetadataProvider metadataProvider, IUrlHelperFactory urlHelperFactory, HtmlEncoder htmlEncoder, ClientValidatorCache clientValidatorCache); public virtual TagBuilder GenerateActionLink(ViewContext viewContext, string linkText, string actionName, string controllerName, string protocol, string hostname, string fragment, object routeValues, object htmlAttributes); public virtual IHtmlContent GenerateAntiforgery(ViewContext viewContext); public virtual TagBuilder GenerateForm(ViewContext viewContext, string actionName, string controllerName, object routeValues, string method, object htmlAttributes); public virtual TagBuilder GenerateLabel(ViewContext viewContext, ModelExplorer modelExplorer, string expression, string labelText, object htmlAttributes); public virtual TagBuilder GenerateTextArea(ViewContext viewContext, ModelExplorer modelExplorer, string expression, int rows, int columns, object htmlAttributes); public virtual TagBuilder GenerateTextBox(ViewContext viewContext, ModelExplorer modelExplorer, string expression, object value, string format, object htmlAttributes); protected virtual TagBuilder GenerateInput(ViewContext viewContext, InputType inputType, ModelExplorer modelExplorer, string expression, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, string format, IDictionary<string, object> htmlAttributes); protected virtual TagBuilder GenerateLink(string linkText, string url, object htmlAttributes); ....省略部分 } |
这个类里面,我们看到了熟悉的TagBuilder,就算不去看它里面的实现都能知道它是用来干嘛的 它就是用来创建我们的Html标签,相信用过MVC的,多多少少都扩展过HtmlHelper,这是类似的。 最后,也是最最重要的重写的Process方法。 可以看到开始就判断了表单<form>中是否包含了action这个属性output.Attributes.ContainsName(HtmlActionAttributeName) 如果包含,就是正常的html标签。换句话说,正常的html写法和我们的TagHelper方法会有冲突,只能用其中一种。 当我们这样写的时候,编译能通过。 但是,运行的时候就会出错。 再下面的处理就是用了TagBuilder去处理了。 收集路由的数据放到一个字典中->区域是否存在->用Generator去创建form表单,返回TagBuilder对象->TagHelperOutput对象把tagbuilder的innerhtml等信息输出。 如下面的写法:
|
1 2 3 |
<form method="post" asp-action="Get" asp-controller="Product" asp-antiforgery="false" asp-route-id="2"> <button type="submit">submit</button> </form> |
生成对应的html如下:
|
1 2 3 |
<form method="post" action="/Product/Get/2"> <button type="submit">submit</button> </form> |
到这里,FormTagHelper的讲解就算是OK,至于其他的,原理都是差不多,就不再累赘了。 来看看,到底有多少种TagHelper(还没有部分没有列出来),以及它们包含的属性。 下面是我们自己写一个TagHelper——CatcherATagHelper,这个TagHelper是干什么的呢?它只是一个精简版的A标签。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; namespace Catcher.EasyDemo.Controllers.TagHelpers { [HtmlTargetElement("catcher-a")] public class CatcherATagHelper:TagHelper { public CatcherATagHelper(IHtmlGenerator generator, IUrlHelperFactory urlHelperFactory) { this.Generator = generator; UrlHelperFactory = urlHelperFactory; } [HtmlAttributeNotBound] public IUrlHelperFactory UrlHelperFactory { get; } protected IHtmlGenerator Generator { get; } public override int Order { get { return -1000; } } public string Action { get; set; } public string Controller { get; set; } public string LinkText { get; set; } [ViewContext] [HtmlAttributeNotBound] public ViewContext ViewContext { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { //method 1 if (Action != null || Controller != null) { output.Attributes.Clear(); var urlHelper = UrlHelperFactory.GetUrlHelper(ViewContext); output.TagName = "a"; output.Attributes.SetAttribute("href", urlHelper.Action(Action, Controller)); //whether the inner html is null if (output.Content.IsEmptyOrWhiteSpace) { output.PreContent.SetContent(LinkText); } } //method 2 //TagBuilder tagBuilder; //if (Action != null || Controller != null) //{ // tagBuilder = Generator.GenerateActionLink( // ViewContext, // linkText: string.Empty, // actionName: Action, // controllerName: Controller, // protocol: string.Empty, // hostname: string.Empty, // fragment: string.Empty, // routeValues: null, // htmlAttributes: null); // output.TagName = "a"; // //whether the inner html is null // if (output.Content.IsEmptyOrWhiteSpace) // { // output.PreContent.SetContent(LinkText); // } // output.MergeAttributes(tagBuilder); //} } } } |
这里提供了两种写法供大家参考 一种是借助IUrlHelperFactory去生成链接 一种是借助IHtmlGenerator去生成链接 写好了之后要怎么用呢? 不知道大家有没有留意_ViewImports.cshtml这个文件
|
1 2 3 |
@using Catcher.EasyDemo.Website @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @inject Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration TelemetryConfiguration |
这个是默认情况下帮我们添加的TagHelper 我们可以在要用到那个TagHelper的地方添加就好 Index.cshtml addTagHelper的用法如下: @addTagHelper 你的TagHelper , 你的TagHelper所在的命名空间 或者更直接 @addTagHelper * , 你的TagHelper所在的命名空间 可以添加,当然也可以删除,删除是@removeTagHelper 当我们在自己的框架中完全重写了一套自己的TagHelper,那么这个时候,微软自己的TagHelper我们就可以通过下面的方法来移除了。 @removeTagHelper […]
View DetailsOcelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由、请求聚合、服务发现、认证、鉴权、限流熔断、并内置了负载均衡器与Service Fabric、Butterfly Tracing集成。这些功能只都只需要简单的配置即可完成,下面我们会对这些功能的配置一一进行说明。 介绍 简单的来说Ocelot是一堆的asp.net core middleware组成的一个管道。当它拿到请求之后会用一个request builder来构造一个HttpRequestMessage发到下游的真实服务器,等下游的服务返回response之后再由一个middleware将它返回的HttpResponseMessage映射到HttpResponse上。 API网关—— 它是系统的暴露在外部的一个访问入口。这个有点像代理访问的家伙,就像一个公司的门卫承担着寻址、限制进入、安全检查、位置引导、等等功能。 Ocelot的基本使用 用一台web service来host Ocelot,在这里有一个json配置文件,里面设置了所有对当前这个网关的配置。它会接收所有的客户端请求,并路由到对应的下游服务器进行处理,再将请求结果返回。而这个上下游请求的对应关系也被称之为路由。 集成Identity Server 当我们涉及到认证和鉴权的时候,我们可以跟Identity Server进行结合。当网关需要请求认证信息的时候会与Identity Server服务器进行交互来完成。 网关集群 只有一个网关是很危险的,也就是我们通常所讲的单点,只要它挂了,所有的服务全挂。这显然无法达到高可用,所以我们也可以部署多台网关。当然这个时候在多台网关前,你还需要一台负载均衡器。 Consul 服务发现 在Ocelot已经支持简单的负载功能,也就是当下游服务存在多个结点的时候,Ocelot能够承担起负载均衡的作用。但是它不提供健康检查,服务的注册也只能通过手动在配置文件里面添加完成。这不够灵活并且在一定程度下会有风险。这个时候我们就可以用Consul来做服务发现,它能与Ocelot完美结合。 集成网关 在asp.net core 2.0里通过nuget即可完成集成,或者命令行dotnet add package Ocelot以及通过vs2017 UI添加Ocelot nuget引用都可以。
|
1 |
Install-Package Ocelot |
配置 我们需要添加一个.json的文件用来添加Ocelot的配置,以下是最基本的配置信息。
|
1 2 3 4 5 6 |
{ "ReRoutes": [], "GlobalConfiguration": { "BaseUrl": "https://api.mybusiness.com" } } |
要特别注意一下BaseUrl是我们外部暴露的Url,比如我们的Ocelot运行在http://123.111.1.1的一个地址上,但是前面有一个 nginx绑定了域名http://api.jessetalk.cn,那这里我们的BaseUrl就是 http://api.jessetalk.cn。 将配置文件加入ASP.NET Core Configuration 我们需要通过WebHostBuilder将我们添加的json文件添加进asp.net core的配置
|
1 2 3 4 5 6 7 8 9 |
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration( (hostingContext,builder) => { builder .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath) .AddJsonFile("Ocelot.json"); }) .UseStartup<Startup>() .Build(); |
配置依赖注入与中间件 在startup.cs中我们首先需要引用两个命名空间
|
1 2 |
using Ocelot.DependencyInjection; using Ocelot.Middleware; |
接下来就是添加依赖注入和中间件
|
1 2 3 4 |
public void ConfigureServices(IServiceCollection services) { services.AddOcelot(); } |
|
1 2 3 4 5 6 7 8 9 |
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseOcelot().Wait(); } |
Ocelot功能介绍 通过配置文件可以完成对Ocelot的功能配置:路由、服务聚合、服务发现、认证、鉴权、限流、熔断、缓存、Header头传递等。在配置文件中包含两个根节点:ReRoutes和GlobalConfiguration。ReRoutes是一个数组,其中的每一个元素代表了一个路由,我们可以针对每一个路由进行以上功能配置。下面是一个完整的路由配置
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
{ "DownstreamPathTemplate": "/", "UpstreamPathTemplate": "/", "UpstreamHttpMethod": [ "Get" ], "AddHeadersToRequest": {}, "AddClaimsToRequest": {}, "RouteClaimsRequirement": {}, "AddQueriesToRequest": {}, "RequestIdKey": "", "FileCacheOptions": { "TtlSeconds": 0, "Region": "" }, "ReRouteIsCaseSensitive": false, "ServiceName": "", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 51876, } ], "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 0, "DurationOfBreak": 0, "TimeoutValue": 0 }, "LoadBalancer": "", "RateLimitOptions": { "ClientWhitelist": [], "EnableRateLimiting": false, "Period": "", "PeriodTimespan": 0, "Limit": 0 }, "AuthenticationOptions": { "AuthenticationProviderKey": "", "AllowedScopes": [] }, "HttpHandlerOptions": { "AllowAutoRedirect": true, "UseCookieContainer": true, "UseTracing": true }, "UseServiceDiscovery": false } |
Downstream是下游服务配置 UpStream是上游服务配置 Aggregates 服务聚合配置 ServiceName, LoadBalancer, UseServiceDiscovery 配置服务发现 AuthenticationOptions 配置服务认证 RouteClaimsRequirement 配置Claims鉴权 RateLimitOptions为限流配置 FileCacheOptions 缓存配置 QosOptions 服务质量与熔断 DownstreamHeaderTransform头信息转发 我们接下来将对这些功能一一进行介绍和配置 路由 路由是API网关最基本也是最核心的功能、ReRoutes下就是由多个路由节点组成。
|
1 2 3 4 |
{ "ReRoutes": [ ] } |
而每一个路由由以下几个基本信息组成: 下面这个配置信息就是将用户的请求 /post/1 转发到 localhost/api/post/1
|
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "DownstreamPathTemplate": "/api/post/{postId}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 80, } ], "UpstreamPathTemplate": "/post/{postId}", "UpstreamHttpMethod": [ "Get"] } |
DownstreamPathTemplate:下游戏 DownstreamScheme:下游服务http schema DownstreamHostAndPorts:下游服务的地址,如果使用LoadBalancer的话这里可以填多项 UpstreamPathTemplate: 上游也就是用户输入的请求Url模板 […]
View Details