netty java_Netty Java快速指南

netty java

使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证,管理和保护。 今天尝试Okta。

Netty是一个无阻塞输入/输出(NIO)框架,它使开发低级网络服务器和客户端变得相对简单。 Netty为需要在套接字级别上工作的开发人员提供了令人难以置信的强大功能,例如在开发客户端和服务器之间的自定义通信协议时。 它支持SSL / TLS,具有阻塞和非阻塞统一API,以及灵活的线程模型。 它又快又高效。

Netty的异步,非阻塞I / O模型是为高度可扩展的体系结构设计的,与类似的阻塞模型相比,它可能允许更高的吞吐量。 基本上,非阻塞服务器在单个线程上异步运行所有请求(没有函数应“阻塞”事件循环)。 这与阻塞服务器模型形成对比,后者通常在单独的线程上运行每个请求。 通过不必在负载增加时切换线程或创建新线程,非阻塞模型可以减少开销,并随着流量增加而更快地进行扩展。

但是,所有这些功能都是以复杂性为代价的。 非阻塞代码通常更难阅读,测试和维护,尽管随着异步范例的成熟,非阻塞代码已大大改善。 由于Netty在套接字级别工作,因此还需要更深入地了解诸如线程循环,字节缓冲区和内存管理之类的细节。

Netty.io团队做了出色的工作,使Netty的所有功能易于使用,但是它仍然比高级库(例如Spring Boot WebFlux)更加复杂。 那么为什么要使用它呢?

Netty旨在使自定义网络协议的实现相对容易。 HTTP很不错,但是它是一种通用协议,基本上适合大多数情况。 但是,如果您始终在服务器和客户端之间来回传递自定义的结构化数据(大型文件,流媒体,实时游戏数据等),则可以做得更好。 Netty允许您编写适合自己特定需求的自己的网络协议,针对特定情况优化流量,而没有HTTP或FTP之类的不必要开销。

但是,即使您不打算编写自己的自定义TCP协议,也可以使用Netty的功能。 Spring WebFlux是Spring对非阻塞和React式编程的解答。 它是传统(阻塞)Spring MVC体系结构的替代方案。 默认情况下,Spring Boot WebFlux Starter在嵌入式Netty服务器上运行。 在此配置中,您可以将WebFlux视为基于Netty的NIO套接字优势构建的React性,非阻塞HTTP应用程序层。

在本教程中,您将在Netty中创建一个基本的“ Hello world”应用程序。 接下来,您将在Spring Boot WebFlux中创建相同的“ Hello world”应用程序。 最后,您将使用Okta作为OAuth 2.0提供程序将OAuth 2.0登录名添加到应用程序中。

安装项目依赖项

在开始之前,该项目需要安装一些必需的工具。

Java 11 :该项目使用Java11 。您可以按照OpenJDK网站上的说明或使用SDKMAN来安装OpenJDK。

HTTPie :这是一个简单的命令行实用程序,用于发出将用于测试REST应用程序的HTTP请求。 Okta开发人员也喜欢它。 按照其网站上的说明进行安装 。

Okta开发人员帐户 :您将Okta用作OAuth / OIDC提供程序,以向应用程序添加OAuth2登录身份验证。 如果尚未注册免费的Okta开发者帐户 ,请注册。

您还应该继续克隆该博客的GitHub存储库 。

<

git clone https://github.com/oktadeveloper/okta-netty-webflux-example.git

该项目包含三个子目录,分别对应于本教程的三个部分:

  1. netty-hello-world :如何创建Netty服务器的非常基本的示例
  2. webflux-hello-world :如何在Spring WebFlux中创建相同的服务器
  3. webflux-oauth2login :如何将OAuth2登录添加到Spring WebFlux应用程序的示例

使用Netty构建HTTP服务器

HTTP服务器是HTTP协议(OSI第7层)的应用层实现,因此在Internet堆栈中相对较高。 如果您正在开发REST API, 那么您将在为您提供此实现的API的基础上进行开发 。 相比之下,Netty并不一定要构建通信,提供会话管理甚至提供像TLS这样的安全性。 如果您要构建超低级网络应用程序,那就太好了; 但是,如果您正在构建REST服务,则可能不是最佳选择。

幸运的是,Netty API还提供了一些帮助程序类和函数,这些类和函数使我们能够轻松集成更高级别的协议(例如HTTP)。 在本部分的教程中,您将使用它们来构建一个简单的HTTP服务器。

在您喜欢的IDE或文本编辑器中打开netty-hello-world项目。

首先,查看src/main/java/com/okta/netty/AppServer.java文件。 此类是应用程序的入口点,用于设置Netty服务器。

package com.okta.netty;  ...public class AppServer {  private static final int HTTP_PORT = 8080;  public void run() throws Exception {  // Create the multithreaded event loops for the serverEventLoopGroup bossGroup = new NioEventLoopGroup();  EventLoopGroup workerGroup = new NioEventLoopGroup();  try {  // A helper class that simplifies server configuration           ServerBootstrap httpBootstrap = new ServerBootstrap();  // Configure the serverhttpBootstrap.group(bossGroup, workerGroup)  .channel(NioServerSocketChannel.class)  .childHandler(new ServerInitializer()) // <-- Our handler created here  .option(ChannelOption.SO_BACKLOG, 128)  .childOption(ChannelOption.SO_KEEPALIVE, true);  // Bind and start to accept incoming connections.  ChannelFuture httpChannel = httpBootstrap.bind(HTTP_PORT).sync(); // Wait until server socket is closedhttpChannel.channel().closeFuture().sync();  }  finally {  workerGroup.shutdownGracefully();  bossGroup.shutdownGracefully();  }  }  public static void main(String[] args) throws Exception {  new AppServer().run();  }  }

最重要的一行是.childHandler(new ServerInitializer()) ,它创建ServerInitializerServerHandler并挂接到Netty服务器。

接下来查看src/main/java/com/okta/netty/ServerInitializer.java 。 此类配置Netty通道,该通道将处理我们的请求并将其连接到ServerHandler

package com.okta.netty;  ...public class ServerInitializer extends ChannelInitializer<Channel> {  @Override  protected void initChannel(Channel ch) {  ChannelPipeline pipeline = ch.pipeline();  pipeline.addLast(new HttpServerCodec());  pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE));  pipeline.addLast(new ServerHandler());  }  }

最后,有src/main/java/com/okta/netty/ServerHandler.java 。 这是映射实际请求并生成响应的地方。

package com.okta.netty; ...public class ServerHandler extends SimpleChannelInboundHandler{  @Override  protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) {  ByteBuf content = Unpooled.copiedBuffer("Hello World!", CharsetUtil.UTF_8);  FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);  response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html");  response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());  ctx.write(response);  ctx.flush();  }  }

在此类中,请注意,您必须将响应字符串转换为字节缓冲区。 实际上,您会生成一个HTTP响应并直接设置一些标头。 这是Internet的应用层(OSI第7层)。 调用ctx.write(response) ,它将响应作为字节流通过TCP发送。 Netty团队在保持低水平的传输协议的同时,为隐藏大量的复杂性做了出色的工作。

测试您的Netty应用

要测试此Netty应用程序,请从项目根目录netty-hello-world运行:

./gradlew run

一旦应用程序完成了加载,就从另一个外壳程序中,使用HTTPie执行GET请求:

$ http :8080HTTP/1.1 200 OK
content-length: 12
content-type: text/htmlHello World!

那是Netty内置的简单HTTP服务器。 接下来,您将爬上梯级的抽象阶梯,并使用Spring Boot和WebFlux简化操作。

在Netty上向WebFlux打个招呼

如前所述,WebFlux是Spring MVC的无阻塞替代方案。 它通过事件驱动,异步和非阻塞方法来处理请求,从而支持React式编程。 它还提供了许多功能性API。 Reactor是与Spring紧密合作开发的React性服务器端Java库,提供了WebFlux的React流方面。 但是,您也可以使用其他React式流库。

回想一下,默认情况下,Spring Boot WebFlux启动程序在Netty服务器上运行。 在下一个示例中,您会注意到Spring Boot隐藏了多少复杂性。

Spring Boot WebFlux项目位于GitHub存储库的webflux-hello-world子目录中。 非常简单。

看一看ReactiveApplication类。 这是准系统的标准Spring Boot应用程序类。 它只是利用public static void main()方法和@SpringBootApplication来启动整个Spring Boot应用程序框架。

src/main/java/com/okta/webflux/app/ReactiveApplication.java

package com.okta.webflux.app;  ... @SpringBootApplication  
public class ReactiveApplication {  public static void main(String[] args) {  SpringApplication.run(ReactiveApplication.class, args);  }  }

ReactiveRouter是一个简单的路由器类,它将HTML端点与处理程序方法链接在一起。 您可以看到它使用依赖注入将ReactiveHandler传递给路由器bean,该bean为/路由定义了一个端点。

src/main/java/com/okta/webflux/app/ReactiveRouter.java

package com.okta.webflux.app;  ...@Configuration  
public class ReactiveRouter {  @Bean  public RouterFunctionroute(ReactiveHandler handler) {  return RouterFunctions  .route(RequestPredicates  .GET("/")  .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::hello);  }  
}

ReactiveHandler同样简单。 它定义了一个返回纯文本的处理函数。 Mono<ServerResponse>返回类型是一种特殊类型,用于返回一个元素的流。 查看有关了解React类型的Spring文档,以了解有关返回类型的更多信息。 如果您习惯使用Spring MVC,则这可能是WebFlux更不熟悉的方面之一。

package com.okta.webflux.app;  ...@Component  
public class ReactiveHandler {  public Mono<ServerResponse> hello() {  return ServerResponse  .ok()  .contentType(MediaType.TEXT_PLAIN)  .body(BodyInserters.fromObject("Hello world!"));  }  }

打开一个外壳,然后导航到项目的webflux-hello-world子目录。

使用以下项目运行项目: ./gradlew bootRun

打开另一个外壳以使用http :8080测试端点。

HTTP/1.1 200 OK
Content-Length: 12
Content-Type: text/plainHello world!

看到使用Spring Boot比Netty简单多少?

创建一个OpenID Connect(OIDC)应用程序

接下来,您将使用OAuth 2.0登录名来保护应用程序。 这听起来可能很复杂,但是不用担心。 Spring和Okta密谋使其变得非常简单!

Okta是SaaS(软件即服务)身份验证和授权提供者。 我们为开发人员提供免费帐户,因此您可以轻松开发OIDC应用程序。 前往developer.okta.com并注册一个帐户。

验证电子邮件后,登录并执行以下步骤(如果这是您第一次登录,则可能需要单击黄色的“ 管理”按钮才能进入开发人员仪表板):

  • 转到应用程序 > 添加应用程序
  • 选择应用程序类型Web ,然后单击下一步
  • 为应用命名。 我将其命名为“ WebFlux OAuth”。
  • 登录重定向URI下, 值更改为http://localhost:8080/login/oauth2/code/okta 。 其余的默认值将起作用。
  • 单击完成

请注意底部的客户端ID客户端密钥 。 稍后您将需要它们。

使用OAuth 2.0保护您的应用安全

在Okta上创建OIDC应用程序后,需要在项目中进行一些更新。 如果您想跳过本部分教程的完成项目,可以在webflux-oauth2login子目录中找到,但是我将向您展示如何修改webflux-hello-world以添加login

首先,将Okta Spring Boot Starter添加到Gradle构建文件中。 我们一直在努力使这一过程尽可能容易,并且Okta Spring Boot Starter简化了OAuth配置。 看看入门的GitHub项目,了解更多信息。

将以下依赖项添加到build.gradle文件的依赖项块中:

dependencies {  ...implementation 'com.okta.spring:okta-spring-boot-starter:1.3.0'
}

接下来,将以下属性添加到src/main/resources/application.properties文件。 您需要将括号中的值替换为您自己的Okta域和客户端ID。

您可以通过打开Okta开发人员仪表板并转到API > 授权服务器并在默认服务器的表中查找来找到您的Issuer URI。 客户端ID和机密来自您刚才创建的OIDC应用程序。

okta.oauth2.issuer={yourIssuerUri}
okta.oauth2.client-id={yourClientId}
okta.oauth2.client-secret={yourClientSecret}

现在运行应用程序: ./gradlew bootRun

注销您的Okta开发人员帐户或使用隐身窗口并浏览至(在浏览器中): http:// localhost:8080 。

系统将指导您使用Okta帐户登录。

登录后,您将被重定向回该应用程序。 是的-成功!

了解有关Netty,Spring Boot和OAuth 2.0的更多信息

在本教程中,您使用Netty创建了一个基本的“ Hello world”应用程序。 您已经看到Netty是一个用于创建TCP和UDP网络协议的超强大框架。 您已经了解了它如何支持非阻塞IO,以及Spring WebFlux如何在Netty之上构建以提供React性,非阻塞HTTP应用程序框架。 然后,您在WebFlux中构建了一个“ Hello world”应用程序,此后,您使用Okta作为OAuth 2.0 / OIDC提供程序来向该应用程序添加OAuth 2.0登录名。

您可以在oktadeveloper / okta-netty-webflux-example上在GitHub上查看本教程的完整代码。

除了WebFlux,在Netty之上还构建了一些强大的网络框架。 Apple最近开放了ServiceTalk的源代码, ServiceTalk是一个支持HTTP,HTTP / 2和gRPC的React性微服务客户端/服务器库。 还有一个Armeria ,一个基于Java 8,Netty,Thrift和gRPC构建的开源异步HTTP / 2 RPC / REST客户端/服务器库。 它的主要目标是帮助工程师构建高性能的异步微服务。

如果您想了解有关Spring Boot,Spring WebFlux和OAuth 2.0的更多信息,请查看以下有用的教程:

  • Spring Boot,OAuth 2.0和Okta入门
  • 使用Spring WebFlux构建React性API
  • OAuth到底是什么?
  • Spring Security 5.0和OIDC入门
  • 身份,声明和令牌– OpenID Connect入门,第1部分,共3部分
  • 使用Spring Boot和GraphQL构建安全的API

如果您对此帖子有任何疑问,请在下面添加评论。 有关更多精彩内容, 请在Twitter上关注@oktadev或订阅我们的YouTube频道 !

使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证,管理和保护。 今天尝试Okta。


翻译自: https://www.javacodegeeks.com/2020/01/a-quick-guide-to-java-on-netty.html

netty java

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331808.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java泛型程序设计——注意擦除后的冲突

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 注意擦除后的冲突 的知识&#xff1b; 1.1&#xff09;当泛型类型被 擦除时&#xff0c; 无法创建引发冲突的条件。 1.1.1&#xff09;看个荔枝&#xff…

java的Swing里怎么new一条线_java – 在JFrame上绘制一条线

我正在尝试使用图形2D绘制一条线,但然后该线出现在所有的线上JFrame中的其他组件因此使它们不可见.我该如何解决这个问题&#xff1f;这是代码&#xff1a;import javax.swing.*;import java.awt.*;import java.awt.geom.*;class Success extends JFrame{public Success(){JPan…

java –cp_Java –缺少字体–崩溃的应用程序!

java –cpEclipse MAT和Heaphero都是分析大型堆转储的流行Java工具。 最近&#xff0c;当我们尝试在Eclipse MAT中分析堆转储文件时遇到了一个有趣的问题。 工具因缺少字体crash而崩溃。 我们认为我们将与您分享发现的结果。 CompositeStrike.getStrikeForSlot&#xff08;&am…

java泛型程序设计——泛型类型的继承原则

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 泛型类型的继承原则 的知识&#xff1b; 【1】泛型类型的继承原则相关 1.1&#xff09;考虑一个类 Employee 和一个Employee子类 Manger &#xff0c; 问&a…

用java代码写美国时间_如何衡量Java代码所用的时间?

本问题已经有最佳答案&#xff0c;请猛点这里访问。我需要分析Java中的一些算法的复杂性。为此&#xff0c;我计划提供大量的输入&#xff0c;并测量Java实现所花费的时间。检查某些代码行之间的时间最精确和准确的方法是什么&#xff1f;我需要精确到毫秒…不完全是&#xff0…

reactor使用方法_Project Reactor展开方法

reactor使用方法最近&#xff0c;我的一位同事向我介绍了Project Reactor类型的expand运算符&#xff0c;在这篇文章中&#xff0c;我想介绍几种使用它的方式。 展开分页结果 考虑在名为City的模型上基于Spring Data的存储库&#xff1a; import org.springframework.data.jpa…

java泛型程序设计——通配符类型+通配符的超类型限定

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 通配符类型通配符的超类型限定 的知识&#xff1b; 【1】通配符类型相关 1.1&#xff09;通配符类型&#xff1a; Pair < ? extends Employee> 表示…

java 延迟初始化_Java并发编程——延迟初始化占位类模式

——仅作笔记使用&#xff0c;内容多摘自《java并发编程实战》在并发编程中&#xff0c;如果状态变量仅在单个线程中初始化和使用&#xff0c;自然是线程安全的&#xff0c;但一旦涉及到线程间的数据交互&#xff0c;如何声明一个用于多线程的单例状态变量才是安全的呢&#xf…

log4j 程序日志_Log4j错误–减慢您的应用程序

log4j 程序日志最近&#xff0c;我们正在对流行的SaaS应用程序进行故障排除。 该应用程序间歇性地变慢。 要从问题中恢复&#xff0c;必须重新启动应用程序。 在高流量期间&#xff0c;此应用有时会变慢。 有时在交通繁忙时也是如此。 没有凝聚力模式。 这类应用程序变慢并重新…

java泛型程序设计——无限定通配符+通配符捕获

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 无限定通配符通配符捕获 的相关知识&#xff1b; 【1】无限定通配符相关 1.1&#xff09;无限定通配符&#xff1a; 如Pair< ?>&#xff1b; 1.1.1…

java方法2数据求和_Leet Code 2 Add Two Numbers - 链表表示的两个数求和 - Java

给定两个链表表示的非负整数&#xff0c;每个节点存储一位数&#xff0c;各位数以逆序存储。将两个数相加&#xff0c;以链表形式返回结果。例如&#xff1a;输入&#xff1a;(2 -> 4 -> 3) (5 -> 6 -> 4)输出&#xff1a;7 -> 0 -> 8/*** Definition for s…

java泛型程序设计——反射和泛型

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 反射和泛型 的相关知识&#xff1b; 【1】反射和泛型相关 1.1&#xff09;现在&#xff0c; Class类是泛型的&#xff0c; 如 String.class 实际上是一个 C…

kafka异步发送数据_在Kafka上异步发送数据

kafka异步发送数据对于一个项目&#xff0c;我试图记录用户的基本交易&#xff0c;例如添加和删除一个项目以及多种类型的项目&#xff0c;并为每笔交易向kafka发送一条消息。 日志机制的准确性不是至关重要的&#xff0c;在kafka服务器停机的情况下&#xff0c;我不希望它阻止…

java按钮权限控制_详解Spring Security 中的四种权限控制方式

Spring Security 中对于权限控制默认已经提供了很多了&#xff0c;但是&#xff0c;一个优秀的框架必须具备良好的扩展性&#xff0c;恰好&#xff0c;Spring Security 的扩展性就非常棒&#xff0c;我们既可以使用 Spring Security 提供的方式做授权&#xff0c;也可以自定义授…

aws 数据库迁移_AWS Loft的数据库周

aws 数据库迁移这是我的笔记&#xff1a; https://databaseweekoctober2019sf.splashthat.com AWS上的数据库&#xff1a;合适工作的合适工具 在许多此类谈话中&#xff0c;我并没有做过深刻的记录。 我正在关注重点。 PostgreSQL排在MySQL之后。 AWS上8种类型的数据库&…

java异常——异常分类+声明已检查异常+如何抛出异常+自定义异常类

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java异常——异常分类声明已检查异常如何抛出异常自定义异常类 的相关知识&#xff1b; 0.2&#xff09;异常处理的任务&#xff1a; 就是将控制权从错误产生的地方转移给能够处…

quarkus_Quarkus入门

quarkusQuarkus – 一个针对OpenJDK HotSpot和GraalVM量身定制的Kubernetes本机Java堆栈&#xff0c;它是从最佳Java库和标准中精制而成的。 –是一个容器优先的框架&#xff0c;针对快速启动时间和低内存消耗进行了优化。 该框架基于许多流行的Java库构建&#xff0c;并且为构…

java异常——捕获异常+再次抛出异常与异常链

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java异常——捕获异常再次抛出异常与异常链 的相关知识&#xff1b; 【1】捕获异常相关 1.1&#xff09;如果某个异常发生的时候没有再任何地方进行捕获&#xff0c; 那程序就会…

java 类似xamarin_xamarin android如何将Java.Lang.Object类型转成C#类型

问题起源其实这个标题也可以换一个更准确一点&#xff0c;因为我遇到的问题是&#xff1a;xamarin android中的Class继承了Java.Lang.Object &#xff0c;将json序列化成c#类型时发现无法赋值&#xff0c;序列化的格式没问题&#xff0c;但是Class的属性值没有复制成功。xamari…

java异常—— finally 子句+带资源的 try语句

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java异常—— finally 子句带资源的 try语句 的相关知识&#xff1b; 【1】 finally 子句相关 1.1&#xff09;产生资源回收问题&#xff1a;当代码抛出一个异常时&#xff0c; …