image frame

C++ 中的左值(Lvalues)和右值(Rvalues)

     C++ 中有两种类型的表达式:

  • 左值(lvalue):指向内存位置的表达式被称为左值(lvalue)表达式。左值可以出现在赋值号的左边或右边。
  • 右值(rvalue):术语右值(rvalue)指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。

     变量是左值,因此可以出现在赋值号的左边。数值型的字面值是右值,因此不能被赋值,不能出现在赋值号的左边。下面是一个有效的语句:

1
int g = 20;

     但是下面这个就不是一个有效的语句,会生成编译时错误:

1
10 = 20;

Java资源大全

Java资源大全中文版

我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理。awesome-java 就是 akullpp 发起维护的 Java 资源列表,内容包括:构建工具、数据库、框架、模板、安全、代码分析、日志、第三方库、书籍、Java 站点等等。伯乐在线已经把 awesome-java 资源列表翻成中文后发布于 ImportNew

Awesome 系列虽然挺全,但基本只对收录的资源做了极为简要的介绍,如果有更详细的中文介绍,对相应开发者的帮助会更大。这也是我们发起这个开源项目的初衷。


我们要做什么?


如何参与本项目?


如何为列表贡献新资源?

欢迎大家为列表贡献高质量的新资源,提交PR时请参照以下要求:

  • 请确保推荐的资源自己使用过
  • 提交PR时请注明推荐理由

资源列表管理收到PR请求后,会定期(每周)在微博转发本周提交的PR列表,并在微博上面听取使用过这些资源的意见。确认通过后,会加入资源大全。

感谢您的贡献!


本项目的参与者

注:名单不分排名,不定期补充更新


目录

古董级工具

这些工具伴随着Java一起出现,在各自辉煌之后还在一直使用。

构建工具

构建及应用依赖关系处理工具。

  • Apache Maven:Maven是一款声明式构建及依赖管理工具,采用约定优于配置方式进行管理。相对Apache Ant更推荐使用Maven,前者采用了过程式管理,维护相对困难。官网
  • Bazel:来自Google的构建工具,可以快速、可靠地构建代码。官网
  • Gradle:使用Groovy(非XML)进行增量构建,可以很好地与Maven依赖管理配合工作。官网
  • Buck:Facebook构建工具。官网

字节码操作

编程方式操作字节码的开发库。

  • ASM:通用底层字节码操作和分析开发库。官网
  • Byte Buddy:使用流式API进一步简化字节码生成。官网
  • Byteman:在运行时通过DSL(规则)操作字节码进行测试和故障排除。官网
  • Javassist:一个简化字节码编辑尝试。官网

集群管理

在集群内动态管理应用程序的框架。

  • Apache Aurora:Apache Aurora是一个Mesos框架,用于长时间运行服务和定时任务(cron job)。官网
  • Singularity:Singularity是一个Mesos框架,方便部署和操作。它支持Web Service、后台运行、调度作业和一次性任务。官网

代码分析

测量代码指标和质量工具。

  • Checkstyle:代码编写规范和标准静态分析工具。官网
  • Error Prone:将常见编程错误作为运行时错误报告。官网
  • FindBugs:通过字节码静态分析查找隐藏bug。官网
  • jQAssistant:使用基于Neo4J查询语言进行代码静态分析。官网
  • PMD:对源代码分析查找不良的编程习惯。官网
  • SonarQube:通过插件集成其它分析组件,对过去一段时间内的数据进行统计。官网

编译器生成工具

用来创建解析器、解释器或编译器的框架。

  • ANTLR:复杂的全功能自顶向下解析框架。官网
  • JavaCC:JavaCC是更加专门的轻量级工具,易于上手且支持语法超前预测。官网

外部配置工具

支持外部配置的开发库。

约束满足问题求解程序

帮助解决约束满足问题的开发库。

  • Choco:可直接使用的约束满足问题求解程序,使用了约束规划技术。官网
  • JaCoP:为FlatZinc语言提供了一个接口,可以执行MiniZinc模型。官网
  • OptaPlanner:业务规划与资源调度优化求解程序。官网
  • Sat4J:逻辑代数与优化问题最先进的求解程序。官网

持续集成

  • Bamboo:Atlassian解决方案,可以很好地集成Atlassian的其他产品。可以选择开源许可,也可以购买商业版。官网
  • CircleCI:提供托管服务,可以免费试用。官网
  • Codeship:提供托管服务,提供有限的免费模式。官网
  • fabric8:容器集成平台。官网
  • Go:ThoughtWork开源解决方案。官网
  • Jenkins:支持基于服务器的部署服务。官网
  • TeamCity:JetBrain的持续集成解决方案,有免费版。官网
  • Travis:通常用作开源项目的托管服务。官网
  • Buildkite: 持续集成工具,用简单的脚本就能设置pipeline,而且能快速构建,可以免费试用。官网

CSV解析

简化CSV数据读写的框架与开发库

  • uniVocity-parsers:速度最快功能最全的CSV开发库之一,同时支持TSV与固定宽度记录的读写。官网

数据库

简化数据库交互的相关工具。

  • Apache Phoenix:HBase针对低延时应用程序的高性能关系数据库层。官网
  • Crate:实现了数据同步、分片、缩放、复制的分布式数据存储。除此之外还可以使用基于SQL的语法跨集群查询。官网
  • Flyway:简单的数据库迁移工具。官网
  • H2:小型SQL数据库,以可以作为内存数据库使用著称。官网
  • HikariCP:高性能JDBC连接工具。官网
  • JDBI:便捷的JDBC抽象。官网
  • jOOQ:为SQL schema生成typesafe代码。官网
  • MapDB:以磁盘或堆内存中并发集合为基础的嵌入式数据库引擎。官网
  • Presto:针对大数据的分布式SQL查询引擎。官网
  • Querydsl:Typesafe统一查询。官网

数据结构

  • Apache Parquet:Google Dremel论文中发布的基于组装算法的列式(Columnar)存储格式。官网
  • Protobuf:Google数据交换格式。官网
  • SBE:简单二进制编码,是最快速的消息格式之一。官网
  • Wire:整洁轻量级协议缓存。官网

时间日期工具库

处理时间和日期的开发库。

  • Joda-Time:在Java 8发布前,Joda-Time是实际使用的时间日期库标准。官网
  • Time4J:高级时间和日期库。官网
  • ThreeTen:JSR-310实现,为JDK提供更具特点的时间和日期API。官网

依赖注入

帮实现依赖翻转范式的开发库。 官网

开发流程增强工具

从最基本的层面增强开发流程。

  • ADT4J:针对代数数据类型的JSR-269代码生成器。官网
  • AspectJ:面向切面编程(AOP)的无缝扩展。官网
  • Auto:源代码生成器集合。官网
  • DCEVM:通过修改JVM在运行时支持对已加载的类进行无限次重定义。官网
  • HotswapAgent:支持无限次重定义运行时类与资源。官网
  • Immutables:类似Scala的条件类。官网
  • JHipster:基于Spring Boot与AngularJS应用程序的Yeoman源代码生成器。官网
  • JRebel:无需重新部署,可以即时重新加载代码与配置的商业软件。官网
  • Lombok:减少冗余的代码生成器。官网
  • Spring Loaded:类重载代理。官网
  • vert.x:多语言事件驱动应用框架。官网

分布式应用

用来编写分布式容错应用的开发库和框架。

  • Akka:用来编写分布式容错并发事件驱动应用程序的工具和运行时。官网
  • Apache Storm:实时计算系统。官网
  • Apache ZooKeeper:针对大型分布式系统的协调服务,支持分布式配置、同步和名称注册。官网
  • Hazelcast:高可扩展内存数据网格。官网
  • Hystrix:提供延迟和容错。官网
  • JGroups:提供可靠的消息传递和集群创建的工具。官网
  • Orbit:支持虚拟角色(Actor),在传统角色的基础上增加了另外一层抽象。官网
  • Quasar:为JVM提供轻量级线程和角色。官网

分布式数据库

对应用程序而言,在分布式系统中的数据库看起来就像是只有一个数据源。

  • Apache Cassandra:列式数据库,可用性高且没有单点故障。官网
  • Apache HBase:针对大数据的Hadoop数据库。官网
  • Druid:实时和历史OLAP数据存储,在聚集查询和近似查询方面表现不俗。官网
  • Infinispan:针对缓存的高并发键值对数据存储。官网
  • TiDB:开源分布式HTAP数据库,结合了传统的RDBMS和NoSQL的最佳特性。官网

发布

以本机格式发布应用程序的工具。

  • Bintray:发布二进制文件版本控制工具。可以于Maven或Gradle一起配合使用。提供开源免费版本和几种商业收费版本。官网
  • Central Repository:最大的二进制组件仓库,面向开源社区提供免费服务。Apache Maven默认使用Central 官网Repository,也可以在所有其他构建工具中使用。
  • IzPack:为跨平台部署建立创作工具(Authoring Tool)。官网
  • JitPack:打包GitHub仓库的便捷工具。可根据需要构建Maven、Gradle项目,发布可立即使用的组件。官网
  • Launch4j:将JAR包装为轻量级本机Windows可执行程序。官网
  • Nexus:支持代理和缓存功能的二进制管理工具。官网
  • packr:将JAR、资源和JVM打包成Windows、Linux和Mac OS X本地发布文件。官网

文档处理工具

处理Office文档的开发库。

  • Apache POI:支持OOXML规范(XLSX、DOCX、PPTX)以及OLE2规范(XLS、DOC、PPT)。官网
  • documents4j:使用第三方转换器进行文档格式转换,转成类似MS Word这样的格式。官网
  • jOpenDocument:处理OpenDocument格式(由Sun公司提出基于XML的文档格式)。官网

函数式编程

函数式编程支持库。

  • Cyclops:支持一元(Monad)操作和流操作工具类、comprehension(List语法)、模式匹配、trampoline等特性。官网
  • Fugue:Guava的函数式编程扩展。官网
  • Functional Java:实现了多种基础和高级编程抽象,用来辅助面向组合开发(composition-oriented development)。官网
  • Javaslang:一个函数式组件库,提供持久化数据类型和函数式控制结构。官网
  • jOOλ:旨在填补Java 8 lambda差距的扩展,提供了众多缺失的类型和一组丰富的顺序流API。官网

游戏开发

游戏开发框架。

  • jMonkeyEngine:现代3D游戏开发引擎。官网
  • libGDX:全面的跨平台高级框架。官网
  • LWJGL:对OpenGL/CL/AL等技术进行抽象的健壮框架。官网
  • jPCT:基于OpenGL技术开发的3D图形引擎。纯Java的3D引擎。官网

GUI

现代图形化用户界面开发库。

高性能计算

涵盖了从集合到特定开发库的高性能计算相关工具。

  • Agrona:高性能应用中常见的数据结构和工具方法。官网
  • Disruptor:线程间消息传递开发库。官网
  • fastutil:快速紧凑的特定类型集合(Collection)。官网
  • GS Collections:受Smalltalk启发的集合框架。官网
  • HPPC:基础类型集合。官网
  • Javolution:实时和嵌入式系统的开发库。官网
  • JCTools:JDK中缺失的并发工具。官网
  • Koloboke:Hash set和hash map。官网
  • Trove:基础类型集合。官网
  • High-scale-lib:Cliff Click 个人开发的高性能并发库官网

IDE

简化开发的集成开发环境。

  • Eclipse:老牌开源项目,支持多种插件和编程语言。官网
  • IntelliJ IDEA:支持众多JVM语言,是安卓开发者好的选择。商业版主要针对企业客户。官网
  • NetBeans:为多种技术提供集成化支持,包括Java SE、Java EE、数据库访问、HTML5等。官网
  • Scala IDE:一款基于Eclipse开源平台打造的Scala集成开发环境。官网
  • SpringSource Tool Suite(STS):一款基于Eclipse开源平台打造的Spring应用开发环境。官网

图像处理

创建、评价和操作图片的支持库。

  • Imgscalr:纯Java 2D实现,简单、高效、支持硬件加速的图像缩放开发库。官网
  • Picasso:安卓图片下载和图片缓存开发库。官网
  • Thumbnailator:Thumbnailator是一个高质量Java缩略图开发库。官网
  • ZXing:支持多种格式的一维、二维条形码图片处理开发库。官网
  • im4java: 基于ImageMagick或GraphicsMagick命令行的图片处理开发库,基本上ImageMagick能够支持的图片格式和处理方式都能够处理。官网
  • Apache Batik:在Java应用中程序以SVG格式显示、生成及处理图像的工具集,包括SVG解析器、SVG生成器、SVG DOM等模块,可以集成使用也可以单独使用,还可以扩展自定义的SVG标签。官网

JSON

简化JSON处理的开发库。

  • Genson:强大且易于使用的Java到JSON转换开发库。官网
  • Gson:谷歌官方推出的JSON处理库,支持在对象与JSON之间双向序列化,性能良好且可以实时调用。官网
  • Jackson:与GSON类似,在频繁使用时性能更佳。官网
  • LoganSquare:基于Jackson流式API,提供对JSON解析和序列化。比GSON与Jackson组合方式效果更好。官网
  • Fastjson:一个Java语言编写的高性能功能完善的JSON库。官网
  • Kyro:快速、高效、自动化的Java对象序列化和克隆库。官网

JVM与JDK

目前的JVM和JDK实现。

基于JVM的语言

除Java外,可以用来编写JVM应用程序的编程语言。

  • Scala:融合了面向对象和函数式编程思想的静态类型编程语言。官网
  • Groovy:类型可选(Optionally typed)的动态语言,支持静态类型和静态编译。目前是一个Apache孵化器项目。官网
  • Clojure:可看做现代版Lisp的动态类型语言。官网
  • Ceylon:RedHat开发的面向对象静态类型编程语言。官网
  • Kotlin:JetBrain针对JVM、安卓和浏览器提供的静态类型编程语言。官网
  • Xtend:一种静态编程语言,能够将其代码转换为简洁高效的Java代码,并基于JVM运行。官网

日志

记录应用程序行为日志的开发库。

  • Apache Log4j 2:使用强大的插件和配置架构进行完全重写。官网
  • kibana:分析及可视化日志文件。官网
  • Logback:强健的日期开发库,通过Groovy提供很多有趣的选项。官网
  • logstash:日志文件管理工具。官网
  • Metrics:通过JMX或HTTP发布参数,并且支持存储到数据库。官网
  • SLF4J:日志抽象层,需要与具体的实现配合使用。官网

机器学习

提供具体统计算法的工具。其算法可从数据中学习。

消息传递

在客户端之间进行消息传递,确保协议独立性的工具。

  • Aeron:高效可扩展的单播、多播消息传递工具。官网
  • Apache ActiveMQ:实现JMS的开源消息代理(broker),可将同步通讯转为异步通讯。官网
  • Apache Camel:通过企业级整合模式(Enterprise Integration Pattern EIP)将不同的消息传输API整合在一起。官网
  • Apache Kafka:高吞吐量分布式消息系统。官网
  • Apache RocketMQ: Apache RocketMQ是一个开源的分布式消息传递和流数据平台。官网
  • Hermes:快速、可靠的消息代理(Broker),基于Kafka构建。官网
  • JBoss HornetQ:清晰、准确、模块化,可以方便嵌入的消息工具。官网
  • JeroMQ:ZeroMQ的纯Java实现。官网
  • Smack:跨平台XMPP客户端函数库。官网
  • Openfire:是开源的、基于XMPP、采用Java编程语言开发的实时协作服务器。 Openfire安装和使用都非常简单,并可利用Web界面进行管理。 官网 GitHub
  • Spark:是一个开源,跨平台IM客户端。它的特性支持集组聊天,电话集成和强大安全性能。如果企业内部部署IM使用Openfire+Spark是最佳的组合。 官网 GitHub
  • Tigase: 是一个轻量级的可伸缩的 Jabber/XMPP 服务器。无需其他第三方库支持,可以处理非常高的复杂和大量的用户数,可以根据需要进行水平扩展。 官网

杂项

未分类其它资源。

  • Design Patterns:实现并解释了最常见的设计模式。官网
  • Jimfs:内存文件系统。官网
  • Lanterna:类似curses的简单console文本GUI函数库。官网
  • LightAdmin:可插入式CRUD UI函数库,可用来快速应用开发。官网
  • OpenRefine:用来处理混乱数据的工具,包括清理、转换、使用Web Service进行扩展并将其关联到数据库。官网
  • RoboVM:Java编写原生iOS应用。官网
  • Quartz:强大的任务调度库.官网

应用监控工具

监控生产环境中应用程序的工具。

原生开发库

用来进行特定平台开发的原生开发库。

  • JNA:不使用JNI就可以使用原生开发库。此外,还为常见系统函数提供了接口。官网

自然语言处理

用来专门处理文本的函数库。

  • Apache OpenNLP:处理类似分词等常见任务的工具。官网
  • CoreNLP:斯坦佛CoreNLP提供了一组基础工具,可以处理类似标签、实体名识别和情感分析这样的任务。官网
  • LingPipe:一组可以处理各种任务的工具集,支持POS标签、情感分析等。官网
  • Mallet:统计学自然语言处理、文档分类、聚类、主题建模等。官网

网络

网络编程函数库。

  • Async Http Client:异步HTTP和WebSocket客户端函数库。官网
  • Grizzly:NIO框架,在Glassfish中作为网络层使用。官网
  • Netty:构建高性能网络应用程序开发框架。官网
  • OkHttp:一个Android和Java应用的HTTP+SPDY客户端。官网
  • Undertow:基于NIO实现了阻塞和非阻塞API的Web服务器,在WildFly中作为网络层使用。官网
  • unirest-java: Unirest 是一个轻量级的 HTTP 请求库,涵盖 Node、Ruby、Java、PHP、Python、Objective-C、.NET 等多种语言。可发起 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS 请求。官网
  • brpc-java: java版baidu rpc框架,高性能、多协议、易扩展、低耦合。官网

ORM

处理对象持久化的API。

  • Ebean:支持快速数据访问和编码的ORM框架。官网
  • EclipseLink:支持许多持久化标准,JPA、JAXB、JCA和SDO。官网
  • Hibernate:广泛使用、强健的持久化框架。Hibernate的技术社区非常活跃。官网
  • MyBatis:带有存储过程或者SQL语句的耦合对象(Couples object)。官网
  • OrmLite:轻量级开发包,免除了其它ORM产品中的复杂性和开销。官网
  • Nutz:另一个SSH。官网Github论坛
  • JFinal:JAVA WEB + ORM框架。官网Github
  • Apache OpenJPA: 实现了 EJB 3.0 中的 JPA 标准,为开发者提供功能强大、使用简单的持久化数据管理框架。 官网

PDF

用来帮助创建PDF文件的资源。

性能分析

性能分析、性能剖析及基准测试工具。

响应式开发库

用来开发响应式应用程序的开发库。

  • Reactive Streams:异步流处理标准,支持非阻塞式反向压力(backpressure)。官网
  • Reactor:构建响应式快速数据(fast-data)应用程序的开发库。官网
  • RxJava:通过JVM可观察序列(observable sequence)构建异步和基于事件的程序。官网

REST框架

用来创建RESTful 服务的框架。

  • Dropwizard:偏向于自己使用的Web框架。用来构建Web应用程序,使用了Jetty、Jackson、Jersey和Metrics。官网
  • Feign:受Retrofit、JAXRS-2.0和WebSocket启发的HTTP客户端连接器(binder)。官网
  • Jersey:JAX-RS参考实现。官网
  • RESTEasy:经过JAX-RS规范完全认证的可移植实现。官网
  • RestExpress:一个Java类型安全的REST客户端。官网
  • RestX:基于注解处理和编译时源码生成的框架。官网
  • Retrofit:类型安全的REST客户端。官网
  • Spark:受到Sinatra启发的Java REST框架。官网
  • Swagger:Swagger是一个规范且完整的框架,提供描述、生产、消费和可视化RESTful Web Service。官网
  • Blade:国人开发的一个轻量级的MVC框架. 它拥有简洁的代码,优雅的设计。官网

科学计算与分析

用于科学计算和分析的函数库。

  • DataMelt:用于科学计算、数据分析及数据可视化的开发环境。官网
  • JGraphT:支持数学图论对象和算法的图形库。官网
  • JScience:用来进行科学测量和单位的一组类。官网

文档索引引擎,用于搜索和分析。

  • Apache Solr:一个完全的企业搜索引擎。为高吞吐量通信进行了优化。官网
  • Elasticsearch:一个分布式、支持多租户(multitenant)全文本搜索引擎。提供了RESTful Web接口和无schema的JSON文档。官网
  • Apache Lucene:是一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。官网

安全

用于处理安全、认证、授权或会话管理的函数库。

  • Apache Shiro:执行认证、授权、加密和会话管理。官网
  • Bouncy Castle,涵盖了从基础的帮助函数到PGP/SMIME操作。官网:多途加密开发库。支持JCA提供者(JCA provider)
  • Cryptomator:在云上进行客户端跨平台透明加密。官网
  • Keycloak:为浏览器应用和RESTful Web Service集成SSO和IDM。目前还处于beta版本,但是看起来非常有前途。官网
  • PicketLink:PicketLink是一个针对Java应用进行安全和身份认证管理的大型项目(Umbrella Project)。官网
  • Sa-Token:Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权 等一系列权限相关问题。官网

序列化

用来高效处理序列化的函数库。

  • FlatBuffers:高效利用内存的序列化函数库,无需解包和解析即可高效访问序列化数据。官网
  • Kryo:快速、高效的对象图形序列化框架。官网
  • FST:提供兼容JDK的高性能对象图形序列化。官网
  • MessagePack:一种高效的二进制序列化格式。官网

应用服务器

用来部署应用程序的服务器。

模板引擎

在模板中替换表达式的工具。

  • Apache Velocity:提供HTML页面模板、email模板和通用开源代码生成器模板。官网
  • FreeMarker:通用模板引擎,不需要任何重量级或自己使用的依赖关系。官网
  • Handlebars.java:使用Java编写的模板引擎,逻辑简单,支持语义扩展(semantic Mustache)。官网
  • Thymeleaf:旨在替换JSP,支持XML文件的工具。官网
  • Beetl:新一代的模板引擎,功能强大,性能良好,超过当前流行的模板引擎。而且还易学易用。官网

测试

测试内容从对象到接口,涵盖性能测试和基准测试工具。

  • Apache JMeter:功能性测试和性能评测。官网
  • Arquillian:集成测试和功能行测试平台,集成Java EE容器。官网
  • AssertJ:支持流式断言提高测试的可读性。官网
  • Awaitility:用来同步异步操作的DSL。官网
  • Cucumber:BDD测试框架。官网
  • Gatling:设计为易于使用、可维护的和高性能负载测试工具。官网
  • Hamcrest:可用来灵活创建意图(intent)表达式的匹配器。官网
  • JMockit:用来模拟静态、final方法等。官网
  • JUnit:通用测试框架。官网
  • Mockito:在自动化单元测试中创建测试对象,为TDD或BDD提供支持。官网
  • PowerMock: 支持模拟静态方法、构造函数、final类和方法、私有方法以及移除静态初始化器的模拟工具。官网
  • REST Assured:为REST/HTTP服务提供方便测试的Java DSL。官网
  • Selenide:为Selenium提供精准的周边API,用来编写稳定且可读的UI测试。官网
  • Selenium:为Web应用程序提供可移植软件测试框架。官网
  • Spock:JUnit-compatible framework featuring an expressive Groovy-derived specification language.官网兼容JUnit框架,支持衍生的Groovy范的语言。
  • TestNG:测试框架。官网
  • Truth:Google的断言和命题(proposition)框架。官网
  • Unitils:模块化测试函数库,支持单元测试和集成测试。官网
  • WireMock:Web Service测试桩(Stub)和模拟函数。官网

通用工具库

通用工具类函数库。

  • Apache Commons:提供各种用途的函数,比如配置、验证、集合、文件上传或XML处理等。官网
  • args4j:命令行参数解析器。官网
  • CRaSH:为运行进行提供CLI。官网
  • Gephi:可视化跨平台网络图形化操作程序。官网
  • Guava:集合、缓存、支持基本类型、并发函数库、通用注解、字符串处理、I/O等。官网
  • JADE:构建、调试多租户系统的框架和环境。官网
  • javatuples:正如名字表示的那样,提供tuple支持。尽管目前tuple的概念还有留有争议。官网
  • JCommander:命令行参数解析器。官网
  • Protégé:提供存在论(ontology)编辑器以及构建知识系统的框架。官网
  • Hutool:一个Java工具集,缓存、HTTP、加密解密、DFA、JSON、分组配置文件、数据库操作、图片验证码、Excel读写、定时任务、模板引擎、邮件、Servlet、二维码、Emoji、分词等一系列工具类。官网

网络爬虫

用于分析网站内容的函数库。

  • Apache Nutch:可用于生产环境的高度可扩展、可伸缩的网络爬虫。官网
  • Crawler4j:简单的轻量级网络爬虫。官网
  • JSoup:刮取、解析、操作和清理HTML。官网
  • webmagic:一个可扩展的Java爬虫框架,架构类似Python的Scrapy。

Web框架

用于处理Web应用程序不同层次间通讯的框架。

  • Apache Tapestry:基于组件的框架,使用Java创建动态、强健的、高度可扩展的Web应用程序。官网
  • Apache Wicket:基于组件的Web应用框架,与Tapestry类似带有状态显示GUI。官网
  • Google Web Toolkit:一组Web开发工具集,包含在客户端将Java代码转为JavaScript的编译器、XML解析器、RCP 官网API、JUnit集成、国际化支持和GUI控件。
  • Grails:Groovy框架,旨在提供一个高效开发环境,使用约定而非配置、没有XML并支持混入(mixin)。官网
  • Ninja:Java全栈Web开发框架。非常稳固、快速和高效。官网
  • Pippo:小型、高度模块化的类Sinatra框架。官网
  • Play:使用约定而非配置,支持代码热加载并在浏览器中显示错误。官网
  • PrimeFaces:JSF框架,提供免费和带支持的商业版本。包括若干前端组件。官网
  • Ratpack:一组Java开发函数库,用于构建快速、高效、可扩展且测试完备的HTTP应用程序。官网
  • Spring Boot:微框架,简化了Spring新程序的开发过程。官网
  • Spring:旨在简化Java EE的开发过程,提供依赖注入相关组件并支持面向切面编程。官网
  • Vaadin:基于GWT构建的事件驱动框架。使用服务端架构,客户端使用Ajax。官网
  • Blade:国人开发的一个轻量级的MVC框架. 它拥有简洁的代码,优雅的设计。官网

业务流程管理套件

流程驱动的软件系统构建。

  • jBPM:非常灵活的业务流程管理框架,致力于构建开发与业务分析人员之间的桥梁。官网
  • Activity:轻量级工作流和业务流程管理框架。官网 github

资源

社区

  • r/java:Reddit的Java子社区。官网
  • stackoverflow:问答平台。官网
  • vJUG:虚拟Java用户组。官网
  • java8 新特性教程例子。github

有影响力的书

具有广泛影响且值得阅读的Java经典书籍。

播客

可以一边编程一边听的东西。

  • Java Council:官网
  • Java Posse:Discontinued as of 02/2015.官网

微博、微信公众号

  • ImportNew:是最受欢迎的、专注Java技术分享的微信公众号。专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。

  • ImportNew 微博:@ImportNew

Twitter

  • Adam Bien:自由职业者、作家、JavaONE明星演讲者、顾问、Java Champion。
  • Antonio Goncalves:Java Champion、JUG Leader、Devoxx France、Java EE 6/7、JCP、作家。
  • Arun Gupta:Java Champion、JavaONE明星演讲者、JUG Leader、Devoxx4Kids成员、Red Hatter。
  • Bruno Borges:Oracle产品经理、Java Jock。
  • Ed Burns:Oracle技术团队顾问。
  • Eugen Paraschiv:Spring安全课程作者。
  • James Weaver:Java、JavaFX、IoT开发者、作者和演讲者。
  • Java EE:Java EE Twitter官方账号。
  • Java Magazine:Java杂志官方账号。
  • Java.net:Java.net官方账号。
  • Java:Java Twitter官方账号。
  • Javin Paul:知名Java博客作者。
  • Lukas Eder:Data Geekery(jOOQ)创始人兼CEO。
  • Mario Fusco:RedHatter、JUG协调、活跃讲师和作者。
  • Mark Reinhold:Oracle首席架构师、Java平台开发组。
  • Martijn Verburg:London JUG co-leader、演讲者、作家、Java Champion等。
  • OpenJDK:OpenJDK官方账号。
  • Reza Rahman:Java EE、GlassFish、WebLogic传道者、作家、演讲者、开源黑客。
  • Simon Maple:Java Champion、virtualJUG创始人、LJC leader、RebelLabs作者。
  • Stephen Colebourne: Java Champion、演讲者。
  • Tim Boudreau:作家、NetBeans大牛。
  • Trisha Gee:Java Champion、演讲者。

微博、微信公众号

  • ImportNew 微博:@ImportNew
  • ImportNew:最受欢迎的、专注Java技术分享的微信公众号。专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。

知名网站

值得关注的Java技术站点。

中文站点

  • ImportNew(ImportNew 专注 Java 技术)

英文站点

Kubernetes的网络模型:Overlay和Underlay

     本文分别介绍 Overlay 网络模型和 Underlay 网络模型。

     Overlay 网络模型物理网络模型中,连通多个物理网桥上的主机的一个简单办法是通过媒介直接连接这些网桥设备,各个主机处于同一个局域网(LAN)之中,管理员只需要确保各个网桥上每个主机的 IP 地址不相互冲突即可。类似地,若能够直接连接宿主机上的虚拟网桥形成一个大的局域网,就能在数据链路层打通各宿主机上的内部网络,让容器可通过自有IP地址直接通信。为避免各容器间的 IP 地址冲突,一个常见的解决方案是将每个宿主机分配到同一网络中的不同子网,各主机基于自有子网向其容器分配 IP 地址。

     显然,主机间的网络通信只能经由主机上可对外通信的网络接口进行,跨主机在数据链路层直接连接虚拟网桥的需求必然难以实现,除非借助宿主机间的通信网络构建的通信“隧道”进行数据帧转发。这种于某个通信网络之上构建出的另一个逻辑通信网络通常即 10.1.2 节提及的 Overlay 网络或Underlay 网络。图 10-7 为 Overlay 网络功能示意图。

图 10-7 Overlay网络功能示意图

     隧道转发的本质是将容器双方的通信报文分别封装成各自宿主机之间的报文,借助宿主机的网络“隧道”完成数据交换。这种虚拟网络的基本要求是各宿主机只需支持隧道协议即可,对于底层网络没有特殊要求。VXLAN 协议是目前最流行的 Overlay 网络隧道协议之一,它也是由 IETF 定义的 NVO3(Network Virtualization over Layer 3)标准技术之一,采用 L2 over L4(MAC-in-UDP)的报文封装模式,将二层报文用三层协议进行封装,可实现二层网络在三层范围内进行扩展,将“二层域”突破规模限制形成“大二层域”。

     那么,同一大二层域就类似于传统网络中 VLAN(虚拟局域网)的概念,只不过在 VXLAN 网络中,它被称作 Bridge-Domain,以下简称为 BD。类似于不同的 VLAN 需要通过 VLAN ID 进行区分,各 BD 要通过 VNI 加以标识。但是,为了确保 VXLAN 机制通信过程的正确性,涉及 VXLAN 通信的 IP 报文一律不能分片,这就要求物理网络的链路层实现中必须提供足够大的 MTU 值,或修改其 MTU 值以保证 VXLAN 报文的顺利传输。不过,降低默认MTU 值,以及额外的头部开销,必然会影响到报文传输性能。VXLAN 的显著的优势之一是对底层网络没有侵入性,管理员只需要在原有网络之上添加一些额外设备即可构建出虚拟的逻辑网络来。这个额外添加的设备称为 VTEP(VXLAN Tunnel Endpoints),它工作于 VXLAN 网络的边缘,负责相关协议报文的封包和解包等操作,从作用来说相当于 VXLAN 隧道的出入口设备。VTEP 代表着一类支持 VXLAN 协议的交换机,而支持 VXLAN 协议的操作系统也可将一台主机模拟为 VTEP,Linux 内核自 3.7 版本开始通过 vxlan 内核模块原生支持此协议。于是,各主机上由虚拟网桥构建的 LAN 便可借助 vxlan 内核模块模拟的 VTEP 设备与其他主机上的 VTEP 设备进行对接,形成隧道网络。同一个二层域内的各 VTEP 之间都需要建立 VXLAN 隧道,因此跨主机的容器间直接进行二层通信的 VXLAN 隧道是各 VTEP 之间的点对点隧道,如图 10-8 所示。

![图10-8 Linux VTEP](/pic/工程/云计算/K8S/Kubernetes的网络模型:Overlay和Underlay/Linux VTEP.png)

     对于 Flannel 来说,这个 VTEP 设备就是各节点上生成 flannel.1 网络接口,其中的“1”是 VXLAN 中的 BD 标识 VNI,因而同一 Kubernetes 集群上所有节点的 VTEP 设备属于 VNI 为 1 的同一个 BD。

     类似 VLAN 的工作机制,相同 VXLAN VNI 在不同 VTEP 之间的通信要借助二层网关来完成,而不同 VXLAN 之间,或者 VXLAN同非 VXLAN 之间的通信则需经由三层网关实现。VXLAN 支持使用集中式和分布式两种形式的网关:前者支持流量的集中管理,配置和维护较为简单,但转发效率不高,且容易出现瓶颈和网关可用性问题;后者以各节点为二层或三层网关,消除了瓶颈。然而,VXLAN 网络中的容器在首次通信之前,源 VTEP 又如何得知目标服务器在哪一个VTEP,并选择正确的路径传输通信报文呢?

     常见的解决思路一般有两种:多播和控制中心。

     多播是指同一个 BD 内的各 VTEP 加入同一个多播域中,通过多播报文查询目标容器所在的目标 VTEP。

     而控制中心则在某个共享的存储服务上保存所有容器子网及相关VTEP的映射信息,各主机上运行着相关的守护进程,并通过与控制中心的通信获取相关的映射信息。Flannel 默认的 VXLAN 后端采用的是后一种方式,它把网络配置信息存储在 etcd 系统上。Linux 内核自 3.7 版本开始支持vxlan 模块,此前的内核版本可以使用 UDP、IPIP 或 GRE 隧道技术。事实上,考虑到当今公有云底层网络的功能限制,Overlay 网络反倒是一种最为可行的容器网络解决方案,仅那些更注重网络性能的场景才会选择 Underlay 网络。

     Underlay 网络模型:Underlay 网络就是传统 IT 基础设施网络,由交换机和路由器等设备组成,借助以太网协议、路由协议和VLAN 协议等驱动,它还是 Overlay 网络的底层网络,为 Overlay 网络提供数据通信服务。容器网络中的 Underlay 网络是指借助驱动程序将宿主机的底层网络接口直接暴露给容器使用的一种网络构建技术,较为常见的解决方案有 MAC VLAN、IP VLAN 和直接路由等。

     MAC VLAN: MAC VLAN 支持在同一个以太网接口上虚拟出多个网络接口,每个虚拟接口都拥有唯一的 MAC 地址,并可按需配置 IP 地址。通常这类虚拟接口被网络工程师称作子接口,但在 MAC VLAN 中更常用上层或下层接口来表述。与 Bridge 模式相比,MAC VLAN 不再依赖虚拟网桥、NAT 和端口映射,它允许容器以虚拟接口方式直接连接物理接口。图 10-9 给出了 Bridge 与 MAC VLAN 网络对比示意图。

图10-9 Bridge与MAC

     MAC VLAN 有 Private、VEPA、Bridge 和Passthru 几种工作模式,它们各自的工作特性如下。

  • Private:禁止构建在同一物理接口上的多个 MAC VLAN 实例(容器接口)彼此间的通信,即便外部的物理交换机支持“发夹模式”也不行。
  • VPEA:允许构建在同一物理接口上的多个 MAC VLAN 实例(容器接口)彼此间的通信,但需要外部交换机启用发夹模式,或者存在报文转发功能的路由器设备。
  • Bridge:将物理接口配置为网桥,从而允许同一物理接口上的多个 MAC VLAN 实例基于此网桥直接通信,而无须依赖外部的物理交换机来交换报文;此为最常用的模式,甚至还是 Docker 容器唯一支持的模式。
  • Passthru:允许其中一个 MAC VLAN 实例直接连接物理接口。

     由上述工作模式可知,除了 Passthru 模式外的容器流量将被 MAC VLAN 过滤而无法与底层主机通信,从而将主机与其运行的容器完全隔离,其隔离级别甚至高于网桥式网络模型,这对于有多租户需求的场景尤为有用。由于各实例都有专用的 MAC 地址,因此 MAC VLAN 允许传输广播和多播流量,但它要求物理接口工作于混杂模式,考虑到很多公有云环境中并不允许使用混杂模式,这意味着 MAC VLAN 更适用于本地网络环境。需要注意的是,MAC VLAN 为每个容器使用一个唯一的 MAC 地址,这可能会导致具有安全策略以防止 MAC 欺骗的交换机出现问题,因为这类交换机的每个接口只允许连接一个 MAC 地址。另外,有些物理网卡存在可支撑的 MAC 地址数量上限。

     IP VLAN IP VLAN 类似于 MAC VLAN,它同样创建新的虚拟网络接口并为每个接口分配唯一的 IP 地址,不同之处在于,每个虚拟接口将共享使用物理接口的 MAC 地址,从而不再违反防止 MAC 欺骗的交换机的安全策略,且不要求在物理接口上启用混杂模式,如图 10-10 所示。

![图10-10 MAC VLAN对比IP VLAN](/pic/工程/云计算/K8S/Kubernetes的网络模型:Overlay和Underlay/MAC VLAN对比IP VLAN.png)

     IP VLAN 有 L2 和 L3 两种模型,其中 IP VLAN L2 的工作模式类似于 MAC VLAN Bridge 模式,上层接口(物理接口)被用作网桥或交换机,负责为下层接口交换报文。

     而 IP VLAN L3 模式中,上层接口扮演路由器的角色,负责为各下层接口路由报文,如图 10-11 所示。IP VLAN L2 模型与MAC VLAN Bridge 模型都支持 ARP 协议和广播流量,它们拥有直接接入网桥设备的网络接口,能够通过 802.1d 数据包进行泛洪和 MAC 地址学习。但 IP VLAN L3 模式下,网络栈在容器内处理,不支持多播或广播流量,从这个意义上讲,它的运行模式与路由器的报文处理机制相同。虽然支持多种网络模型,但 MAC VLAN 和 IP VLAN 不能同时在同一物理接口上使用。Linux 内核文档中强调,MAC VLAN 和 IP VLAN 具有较高的相似度,因此,通常仅在必须使用 IP VLAN 的场景中才不使用 MAC VLAN。一般说来,强依赖于 IP VLAN 的场景有如下几个:

  • Linux 主机连接到的外部交换机或路由器启用了防止 MAC 地址欺骗的安全策略;
  • 虚拟接口的需求数量超出物理接口能够支撑的容量上限,并且将接口置于混杂模式会给性能带来较大的负面影响;
  • 将虚拟接口放入不受信任的网络名称空间中可能会导致恶意的滥用。

图10-11 IP VLAN的L2和L3模型

     需要注意的是,Linux 内核自 4.2 版本后才支持 IP VLAN 网络驱动,且在 Linux 主机上使用 ip link 命令创建的 802.1q配置接口不具有持久性,因此需依赖管理员通过网络启动脚本保持配置。

     直接路由 “直接路由”模型放弃了跨主机容器在 L2 的连通性,而专注于通过路由协议提供容器在 L3 的通信方案。这种解决方案因为更易于集成到现在的数据中心的基础设施之上,便捷地连接容器和主机,并在报文过滤和隔离方面有着更好的扩展能力及更精细的控制模型,因而成为容器化网络较为流行的解决方案之一。

图10-12 直接路由虚拟网络示意图

一个常用的直接路由解决方案如图 10-12 所示,每个主机上的各容器在二层通过网桥连通,网关指向当前主机上的网桥接口地址。跨主机的容器间通信,需要依据主机上的路由表指示完成报文路由,因此每个主机的物理接口地址都有可能成为另一个主机路由报文中的“下一跳”,这就要求各主机的物理接口必须位于同一个 L2 网络中。于是,在较大规模的主机集群中,问题的关键便转向如何更好地为每个主机维护路由表信息。常见的解决方案有:

  • Flannel host-gw 使用存储总线 etcd 和工作在每个节点上的 flanneld 进程动态维护路由;
  • Calico 使用 BGP(Border Gateway Protocol)协议在主机集群中自动分发和学习路由信息。与 Flannel 不同的是,Calico 并不会为容器在主机上使用网桥,而是仅为每个容器生成一对 veth 设备,留在主机上的那一端会在主机上生成目标地址,作为当前容器的路由条目,如图 10-13 所示。

图10-13 Calico的直接路由模型示意图

     Calico 的直接路由模型示意图显然,较 Overlay 来说,无论是 MAC VLAN、IP VLAN 还是直接路由机制的 Underlay 网络模型的实现,它们因无须额外的报文开销而通常有着更好的性能表现,但对底层网络有着更多的限制条件。

工作的意义

       工作的目的是为了赚钱,赚不到钱就获取认知、经历和阅历,不应该因为工作而失去生活的意义。

TCP报文结构和功能简析

1、简介

     TCP:传输、控制、协议。

     TCP 与UDP 最大却别就在那个C上面,它充分实现了数据传输时各种控制功能。可以进行丢包重发控制,还可以对次序乱掉的数据包进行顺序控制,还能控制传输流量,这些是UDP中没有的。即 TCP 提供一种面向连接的、可靠的字节流服务。TCP 是一中面向有链接的协议,只有在确认对端存在的时候,才会发送分数据,从而也可以控制通信流量的浪费。

     什么是可靠的传输:不丢包、不损坏、不乱序、不重复。TCP 通过校验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制来实现可靠传输。接收端查询就收数据 TCP 首部中的序号和数据长度。将自己下一步应该接受的序列号作为确认应答返送回去。就这样,通过序列号和确认应答,TCP 实现可靠传输。一般使用 TCP 首部用于控制的字段来管理连接。一个连接的建立和断开,正常过程中,至少需要来回共 7 个包才能完成。

2、TCP首部

     TCP首部的数据结构如图所示:

TCP首部

     为了便于理解,忽略选项部分,固定首部通常为20个字节,将按作用分类分析。

2.1、端口号(port)

     前 4 个字节来标识了发送方的端口号和接收方的端口号,即该数据包由谁发送,由谁接收。前 2 个字节标识源端口号,紧接着 2 个字节标识目的端口号。

     即发送方:(11111111,1111111)2 = (65535)10,除去0~1023。

     即接收方:(11111111,1111111)2 = (65535)10,除去0~1023。

2.2、序号(seq)

     TCP 是面向字节流的。在一个 TCP 连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置。首部中的序号字段值则是指的是本报文段所发送的数据的第一个字节的序号。长度为 4 字节,序号是 32bit 的无符号数,序号到达 2(32次方) - 1 后又从 0 开始。

2.3、确认号(ack)

     ack:确认序号,即确认字节的序号,更确切地说,是发送确认的一端所期望收到的下一个序号。所谓的发送确认的一端就是将确认信息发出的一端。比如第二次握手的S端就是发送确认的一端。确认序号为上次接收的最后一个字节序号加1.只有确认标志位(ACK)为1的时候,确认序号才有效。

2.4、数据偏移

     也叫首部长度,占4个bit,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。

TCP首部

     由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的。“首部长度”是 4 位二进制数,单位是32位字,能表示的最大十进制数字是 15。(1111)2=(15)10,即是 15 个 32 位,一个 32 位是 4 个字节,因此数据偏移的最大值是 15x4=60 个字节,这也是 TCP 首部的最大字节。因为固定首部的存在,数据偏移的值最小为20个字节,因此选项长度不能超过40字节*(减去20个字节的固定首部)。

2.5、保留(reserve)

     占 6 位,保留为今后使用,但目前应置为 0。

2.6、紧急URG(urgent)

     当 URG=1 时,表明紧急指针字段有效。

     它告诉系统此报文段中有紧急数据,应尽快发送(相当于高优先级的数据),而不要按原来的排队顺序来传送。

     例如,已经发送了很长的一个程序要在远地的主机上运行。但后来发现了一些问题,需要取消该程序的运行,因此用户从键盘发出中断命令。如果不使用紧急数据,那么这两个字符将存储在接收TCP的缓存末尾。只有在所有的数据被处理完毕后这两个字符才被交付接收方的应用进程。这样做就浪费了很多时间。

     当 URG 置为 1 时,应用进程就告诉 TCP 有紧急数据要传送。于是 TCP 就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍然是普通数据。这时要与首部中紧急指针(Urgent Pointer)字段配合使用。

2.7、确认ACK(acknowledgment)

     仅当ACK = 1时确认号字段才有效,当ACK = 0时确认号无效。TCP规定,在连接建立后所有的传送的报文段都必须把ACK置为1。

2.8、推送 PSH(push)

     当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应。在这种情况下,TCP就可以使用推送(push)操作。发送方TCP把PSH置为1,并立即创建一个报文段发送出去。接收方TCP收到PSH=1的报文段,就尽快地(即“推送”向前)交付接收应用进程。而不用再等到整个缓存都填满了后再向上交付。

2.9、复位RST(reset)

     当RST=1时,表明TCP连接中出现了严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立传输连接。RST置为1还用来拒绝一个非法的报文段或拒绝打开一个连接。

2.10、同步SYN(synchronization)

     在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1。

     因此SYN=1就表示这是一个连接请求或连接接受报文。

2.11、终止FIN(finis,意思是“完”“终”)

     用来释放一个连接。当FIN=1时,表明此报文段的发送发的数据已发送完毕,并要求释放运输连接。

2.12、窗口

     占2字节。窗口值是(0,216 -1)之间的整数。窗口指的是发送本报文段的一方的接受窗口(而不是自己的发送窗口),窗口大小是给对方用的。窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方一次发送的数据量(以字节为单位)。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。

     总之,窗口值作为接收方让发送方设置其发送窗口的依据。

     例如,A发送了一个报文段,其确认号是3000,窗口字段是1000.这就是告诉对方B:“从3000算起,A接收缓存空间还可接受1000个字节数据,字节序号是3000-3999”,可以想象到河道的阀门。

     总之:窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化。

2.13、检验和

     占2字节。检验和字段检验的范围包括首部和数据这两部分。和UDP用户数据报一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。伪首部的格式和UDP用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6(TCP的协议号是6);把第5字段中的UDP中的长度改为TCP长度。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用TPv6,则相应的伪首部也要改变。

2.14、紧急指针

     占2字节。紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据) 。因此,在紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为0时也可以发送紧急数据。

2.15、选项

     长度可变,最长可达40个字节。当没有使用“选项”时,TCP的首部长度是20字节。

2.16、最大报文段长度

     最大报文段长度(MSS:Maximum Segment Size)表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。

     当建立一个连接时,每一方都有用于通告它期望接收的MSS选项(MSS选项只能出现在SYN报文段中),如果一方不接收来自另一方的MSS值,则MSS就定为默认值536字节(这个默认值允许20字节的IP首部和20字节的TCP首部以适合576字节IP数据报) 。

     为什么要规定一个最大报文长度MSS呢?这并不是考虑接受方的接收缓存可能存放不下TCP报文段中的数据。实际上,MSS与接收窗口值没有关系。我们知道,TCP报文段的数据部分,至少要加上40字节的首部(TCP首部20字节和IP首部20字节,这里还没有考虑首部中的可选部分)才能组装成一个IP数据报。若选择较小的MSS长度,网络的利用率就降低。设想在极端情况下,当TCP报文段只含有1字节的数据时,在IP层传输的数据报的开销至少有40字节(包括TCP报文段的首部和IP数据报的首部)。这样,对网络的利用率就不会超过1/41。到了数据链路层还要加上一些开销。但反过来,若TCP报文段非常长,那么在IP层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片组成成原来的TCP报文段,当传输出错时还要进行重传,这些也都会使开销增大。
     因此,MSS应尽可能大些,只要在IP层传输时不需要分片就行。

     由于IP数据报所经历的路径是动态变化的,因此在这条路径上确定的不需要的分片的MSS,如果改走另一条路径就可能需要进行分片。因此最佳的MSS是很难确定的。在连接过程中,双方都把自己能够支持的MSS写入这一字段,以后就按照这个数值传输数据,两个传送方向可以有不同的MSS值。若主机未填写这一项,则MSS的默认值是536字节长。因此,所有在互联网上的主机都应该接受的报文段长度是536+20(固定首部长度)=556字节。

     后来又增加了几个选项如窗口扩大选项、时间戳选项等。

2.17、窗口扩大选项

     窗口扩大选项是为了扩大窗口。

     我们知道,TCP首部中窗口字段长度是16位,因此最大的窗口大小为64K字节。虽然这对早期的网络是足够用的,但对于包含卫星信道的网络,传播时延和宽带都很大,要获得高吞吐量需要更大的窗口大小。

     窗口扩大选项占3字节,其中有一个字节表示移位值S。新的窗口值等于TCP首部中的窗口位数从16增大到(16+S)。移位值允许使用的最大值是14,相当于窗口最大值增大到2(16+14)-1=230-1。

     窗口扩大选项可以在双方初始建立TCP连接时进行协商。如果连接的某一端实现了窗口扩大,当它不再需要扩大其窗口时,可发送S=0选项,使窗口大小回到16。

2.18、时间戳选项

     时间戳选项占10字节,其中最主要的字段是时间戳字段(4字节)和时间戳回送回答字段(4字节)。时间戳选项有以下两个概念:

     第一、 用来计算往返时间RTT。发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段复制到时间戳回送回答字段。因此,发送方在收到确认报文后,可以准确地计算出RTT来。

     第二、 用于处理TCP序号超过232 的情况,这又称为防止序号绕回PAWS。我们知道,TCP报文段的序号只有32位,而每增加232 个序号就会重复使用原来用过的序号。当使用高速网络时,在一次TCP连接的数据传送中序号很可能被重复使用。例如,当使用1.5Mbit/s的速度发送报文段时,序号重复要6小时以上。但若用2.5Gbit/s的速率发送报文段,则不到14秒钟序号就会重复。为了使接收方能够把新的报文段和迟到很久的报文段区分开,则可以在报文段中加上这种时间戳。

数据链路层

1、概述

     数据链路层是TCP/IP协议栈的第二层!数据链路层的传输单元:帧(也就是传输单位)。

数据链路层

     帧的结构如下:

  • 帧结构的构成:MAC子层 + 上三层数据 + FCS

帧结构

  • 比喻:一个帧我们可以理解为一辆火车,MAC子层是火车头,上三层数据为乘客,FCS为火车尾巴
  • MAC子层头部包含(也叫帧头):目标MAC地址(6字节) 源MAC地址(6字节) 类型(2字节)
  • MAC地址:也称为物理地址,是被固化到网卡的全球唯一标识,如下图:

Mac 地址结构

     注释:MAC地址=厂家标识+内部编号====实现了全球唯一!怎么查看自己的MAC地址?开始运行–cmd–ipconfig /all

  • 类型字段的作用:区分上层协议,0806代表上层协议是ARP协议,0800代表上层是IP协议
  • 上三层数据:也就是3层包头+4层包头+5层数据。其中一个帧是有最大承载能力限制的。也就是一个帧中的上三层数据就是乘客,而一辆火车中的乘客是又上限的,一个帧的最大承受能力叫MTU值,目前国际标准为1500字节
  • MTU:(最大传输单元)1500字节
  • 帧尾:FCS=帧校验,长度4个字节,作用是校验整个帧在传输过程中是否发生传输错误。

     帧结构最终效果图如下:

帧结构效果图

     经典问题:请描述一下帧结构?

     答:帧是由帧头+上三层数据+帧尾,帧头包含目MAC,源MAC,类型,帧尾是FCS,MTU:1500

2、本层设备

     工作在2层的设备:交换机/网桥

3、交换机的工作原理

     经典问题:请描述一下交换机的工作原理。

     答:

     1)当收到一个帧,首先学习帧中的MAC地址来形成自己的MAC地址表!

     2)然后检查帧中的目标MAC地址,并匹配MAC地址表。

        如表中匹配成功,则单播转发!

        如表中无匹配项,则广播转发!

     3)MAC地址表的老化时间是?300秒!

     效果图如下:

交换机的工作原理

4、如何配置交换机

     傻瓜式交换机一般是不支持管理和配置的!企业级交换机支持配置高级功能及高级配置,价格要高,一般称为管理型交换机!如购买一台华为或者思科交换机,看下图:

交换机

     一般会自带一根console线!看下图:

console线

     建议再买一根com口转USB线,看下图:

com口转USB线

     使用console线+转换usb线,来连接交换机的console口与电脑的USB接口,如下图:

交换机接线

     然后再电脑上打开超级终端(xp上自带,win7另行下载即可),即可看到配置界面。当然我们可以使用思科的模拟软件来做实验,如cisco packettracer

谈谈云原生

     之前关于云计算技术底座的部门会谈,我本着程序员实事求是的态度,表示自己其实并不懂云原生。前段时间云技术底座的模型验证,遇到一个测试案例叫做“白屏纳管”,意思是指 CAAS 平台能够对包括云下硬件负载 F5、A10,云上 SLB 等设备进行管理。云原生技术有着太多的这种花里胡哨的名词,将本来很简单的一件事情包装出个能吓住人的词,来提高理解的门槛。作为一个一线开发,我有一种很深切的感受:很多优秀的设计,都是有着简洁优雅的设计原理或者说思想蕴含其中。这种没什么太多内涵的毫无意义的造词运动,对于工程实践,没有任何好处。我们不应该人云亦云盲目从众,也不应该以偏概全一叶障目。

     以下是阿里云公众号某产品经理关于云原生的解释,我截了图如下:

阿里云云原生公众号某文章

     这段话讲得没有问题,但是似乎又什么都没讲,对于云原生的定义,这种似是而非的说法显然不是一线开发人员想要的答案。

     我们在说云原生的时候,其实是在说“云原生计算”,云原生这个词其实可以拆为“云”和”原生“两个词,这其中其实隐藏了一个词——“云计算”。云原生一定是云计算, 这就要求我们事先已经对云计算的发展历史有所了解。云原生与云计算的区别便在“原生”二字上,那么理解云原生,重点就在理解其为何为“原生”。我这里用一句话来总结云原生:云原生是为了发挥出云计算所有优势的最短路径(这句精辟的提炼摘自《阿里云云原生架构实践》一书)。

     这些想法和做法归纳为三个方面:应用架构、计算模型、代表技术。

  • 代表技术 是最容易理解的。代表技术可以是一些狭义上的云原生基础设施,包含了相关的软件或硬件技术,例如裸金属、docker、K8S;也可以是泛化的一些工程技术体系,比如 Spring Cloud,DevOps,DDD ——它们与云基础设施不一样,很多并非为了云原生而生的,但是在云上环境表现活跃,也可以归纳到云原生代表技术中来。有些人说,使用了容器技术,就是云原生,这肯定是不准确的。容器其实只是改变了我们应用的部署方式,应用运行时的形态,以此来定义云原生是非常片面的。

  • 计算模型, 既然这个行业这么喜欢遣词造句,那我也造几个词(切,谁还不会啊!!!)。计算模型可以从两个方面来看:

     计算的服务模型: 计算的服务模型是从商业的角度看的。我们从传统的购买硬件送软件,到购买软件和维护再到如今购买云服务,云计算平台将计算、存储、网络像煤电一样卖给我们。需要指出,计算资源的这种服务模型并不是在云原生中才强调的,而是从云计算提出的时候,就已经强调了的。

     服务的计算模型: 这个语境中,“服务”不再是商业上的“服务”,而是指“应用服务”。应用服务的计算模型,强调了应用程序的可伸缩性、弹性、自动化和可维护性,以适应现代云环境中的需求。当然,应用的可伸缩、弹性自动化运维这些并不是应用自身具备的能力,而是在云上环境被赋予的,但是需要从应用侧做一定的改造工作,“以适应现代云环境中的需求”,比如下面要说的——应用架构。

  • 应用架构 为了最大化发挥云原生的计算优势,应用侧应该也要做架构升级——例如微服务化,在弹性扩缩的时候以更细的粒度进行算力分配,更精确的分配云计算底座资源(计算、存储、网络)——当然,这只是我简单作示意的一种说法。这种说法换个侧面来看,单体应用就不能上云计算么?当然可以,但是那就不叫云原生了,因为单体无法发挥出云计算的最大优势。

     所以从我自己目前的工作经历总结如下: 云原生一定是云计算,特别的,云原生是有效发挥出云计算所有优势的最短路径。理解云原生,可以从代表技术、云原生计算模型、云原生应用架构三方面着手理解。

  • Copyrights © 2017 - 2025 杨海波
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信