为什么我们需要API网关?(Why do we need API Gateway?)

To understand this pattern we must delve into the real life problems, in the microservices world. We will continue with the example of our e-commerce system. In the previous exercise, we already built Product Catalog Service, which is responsible to manage product lifecycle through — create, update, delete and get operations. Lets go through some common scenarios, you might come across, while developing the microservices.

要了解这种模式,我们必须深入研究微服务世界中的现实生活中的问题。 我们将继续以电子商务系统为例。 在上一个练习中,我们已经构建了产品目录服务,产品目录服务负责通过创建,更新,删除获取操作来管理产品生命周期。 在开发微服务时,让我们经历一些常见的场景,您可能会遇到。

方案1-服务的多个版本 (Scenario 1 — Multiple Versions of Service)

Our Product Catalog Service is updated with the new changes, but the updated service is not compatible with the mobile client.

我们的产品目录服务已通过新更改进行了更新,但是更新的服务与移动客户端不兼容。

Though we cannot achieve the service update completely, we can optimize it by running multiple versions in parallel. Our mobile client will continue using the V1 while other clients will move to V2.

尽管我们无法完全实现服务更新,但是我们可以通过并行运行多个版本来对其进行优化。 我们的移动客户端将继续使用V1,而其他客户端将移至V2。

方案2-限制访问 (Scenario 2 — Restricted Access)

Our Product Catalog Service provides apis to both read and write the catalog data.

我们的产品目录服务提供了用于读取和写入目录数据的api。

Our security team suggests to limit the access of write apis — add, update and delete, from the vendor portal only — vendor.test-gateway-store.com.

我们的安全团队建议限制对写入api的访问-仅可从供应商门户( vendor.test-gateway-store.com)添加,更新和删除

Rest of the clients, like e-commerce portal, can only access get product api from Product Catalog Service.

其他客户(例如电子商务门户)只能从Product Catalog Service访问get product api

方案3-监视Api性能 (Scenario 3 — Monitoring Api Performance)

Lot of customers are complaining delays while getting the product details. We must monitor the performance of “get product details” api to assess the severity and plan out the next steps.

许多客户抱怨获得产品详细信息时延误。 我们必须监视“获取产品详细信息” api的性能,以评估严重性并计划下一步。

方案4-更新响应标头 (Scenario 4 — Updating Response Header)

We received the performance statistics of Product Catalog Service. Get product details api is getting hit too many times. This is not needed as the product details are not updated every minute.

我们收到了产品目录服务的性能统计数据。 获取产品详细信息api被击中太多次了。 不需要此操作,因为产品详细信息不会每分钟更新一次。

We can avoid the unnecessary hits by introducing Cache-Control header attribute in the response of get product details api.

我们可以通过在获取产品详细信息api的响应中引入Cache-Control标头属性来避免不必要的点击

The above discussed scenarios typically fall into the category of cross cutting concerns and must be dealt separately . This will increase the maintainability and agility of overall system. Also if the changes are done in code, its going to create longer delivery timelines. The API Gateway pattern provides a cleaner approach to resolve such issues.

上面讨论的场景通常属于交叉关注的类别,必须单独处理。 这将增加整个系统的可维护性和敏捷性。 同样,如果更改是在代码中完成的,则将创建更长的交付时间表。 API网关模式 提供了一种更清洁的方法来解决此类问题。

API网关如何工作? (How API Gateway Works?)

The API gateway takes all the api calls, from the clients and route them to appropriate microservice(s) with request routing, composition, and protocol translation.

API网关从客户端接收所有api调用,并将它们路由到具有请求路由,组合和协议转换的适当微服务。

API Gateway — An Illustration
API网关—插图

Exactly what the API gateway does will vary from one implementation to another. Some common functions include routing, rate limiting, billing, monitoring, authentication, api composition, policies, alerts, and security.

确切地说, API网关所做的工作因一个实现而异。 一些常用功能包括路由,速率限制,计费,监视,身份验证,API组成,策略,警报和安全性。

We will be implementing the gateway pattern to solve the problems, we discussed above. These sample implementations are primarily based on Spring Cloud Gateway. This library is the preferred gateway implementation provided by Spring Cloud. Its built with Spring 5, Spring Boot 2 and Project Reactor.

我们将实现上面讨论的网关模式来解决问题。 这些示例实现主要基于Spring Cloud Gateway。 该库是Spring Cloud提供的首选网关实现 它使用Spring 5,Spring Boot 2Project Reactor构建。

Spring Cloud Gateway的核心功能 (The core functions of Spring Cloud Gateway)

Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency. The framework is based on three core components — Routes, Predicates and Filters.

Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域的关注点,例如:安全性,监视/度量和弹性。 该框架基于三个核心组件-路由,谓词过滤器。

路线 (Routes)

This is the primary component consisting of ID, Destination Uri, Predicates and Filters.

这是主要组件,由ID,Destination Uri,PredicatesFilters组成

谓词 (Predicates)

This is more like a condition to match the route. This is done based on the HTTP request, headers, parameters, path, cookie and other request criteria.

这更像是匹配路线的条件。 这是根据HTTP请求,标头,参数,路径,cookie和其他请求条件完成的。

筛选器 (Filters)

They are the plugins to update the request or response. They function similar to the servlet filters with the pre and post variations. You can use it for multiple purpose including “adding a request parameter”, “adding a response header”, “monitoring”, and many other utilities.

它们是用于更新请求或响应的插件。 它们的功能与servlet过滤器类似,但具有前后变化。 您可以将其用于多种用途,包括“添加请求参数”,“添加响应头”,“监视”以及许多其他实用程序。

We will see the examples for each of these aspects through the sample implementations in the next section.

在下一节中,我们将通过示例实现来查看这些方面的示例。

实施Api网关 (Implementing Api Gateway)

In this section, we will implement our Api Gateway and build the solutions mapped to the scenarios discussed earlier.

在本节中,我们将实现Api网关并构建映射到前面讨论的方案的解决方案。

方案1-服务的多个版本。 (Scenario 1 — Multiple versions of a service.)

As discussed earlier, we will have two version of our Product Catalog Service — V1 & V2. Lets create Product Catalog Service based on Spring Boot as explained in our very first series — Developing First Service. Assuming you are already aware of creating a Spring Boot based service, we will work on updating the Product Catalog Service.

如前所述,我们将提供两个版本的产品目录服务-V1和V2。 让我们 如第一个系列“开发第一服务”中所述,基于Spring Boot创建产品目录服务。 假设您已经知道创建基于Spring Boot的服务,我们将致力于更新Product Catalog Service

Lets introduce a new method — getVersion in this service, which does a simple job to display the service version.

让我们在该服务中引入一个新方法getVersion ,它可以很简单地显示服务版本

@RestControllerpublic class ProductCatalogService { ... @GetMapping("/product/version") public String getVersionInfo(){  return "Version - V1"; }}

Copy the whole project to create a new version of our Product Catalog Service. Implement the getVersion method similar to the one above. The only difference is the version name — V2.

复制整个项目以创建我们产品目录服务的新版本 实现类似于上述方法的getVersion方法。 唯一的区别是版本名称-V2。

@RestControllerpublic class ProductCatalogService { ... @GetMapping("/product/version") public String getVersionInfo(){  return "Version - V2"; }}

Update the respective application properties to avoid the port conflicts. We will be running Version 1 on port 8081 and Version 2 on port 8082.

更新相应的应用程序属性,以避免端口冲突。 我们将在端口8081上运行版本1,在端口8082运行版本2。

server.port=8081 #8081 for V1 and #8082 for V2

Run both the service versions with the maven command mvn spring-boot:run , in the respective directories. You should be able to view the specific versions by visiting http://localhost:8081/product/version or http://localhost:8082/product/version urls.

使用maven命令mvn spring-boot:run在相应目录中运行两个服务版本。 您应该能够通过访问http://localhost:8081/product/versionhttp://localhost:8082/product/version URL来查看特定版本。

Its time to create our API Gateway server. Lets go to our favorite store to create Spring Boot application — The Spring Initializer. Add the Spring Cloud Gateway dependency.

是时候创建我们的API网关服务器了。 让我们去我们最喜欢的商店创建Spring Boot应用程序-Spring Initializer 。 添加Spring Cloud Gateway依赖项。

Generate, download and unpack the archive to your local system. Open the project with your favorite code editor. We will be creating src/main/resources/application.yml file for the gateway server configuration.

生成,下载归档文件并将其解压缩到本地系统。 使用您喜欢的代码编辑器打开项目。 我们将为网关服务器配置创建src/main/resources/application.yml文件。

server:  port: 9090spring:  cloud:    gateway:     routes:      - id: product_service_v1        uri: 'http://localhost:8081'        predicates:          - Path=/product/**          - Query=src,mobile      - id: product_service_v2        uri: 'http://localhost:8082'        predicates:          - Path=/product/**

We are defining two routes here — product_service_v2 and product_service_v1 . The first version can only be accessed by Mobile devices. We are using two predicates for product_service_v1 to achieve this —

我们在此处定义两条路由product_service_v2product_service_v1 。 第一个版本只能由移动设备访问。 我们使用product_service_v1两个谓词来实现这一目标-

  • Path (/product/**) — This will match the path pattern containing ‘/product’ with any suffix.

    路径(/ product / **)-这将匹配包含“ / product”和任何后缀的路径模式。

  • Query (src,mobile) — This will match the query parameter in the path if src parameter is available and has a value mobile

    查询(src,mobile)-如果src参数可用并且值为mobile ,则它将与路径中的查询参数匹配

If both the conditions meet, the request will be forwarded to http://localhost:8081 as specified against uri attribute. If only the path matches, request will be forwarded to http://localhost:8082 .

如果两个条件都满足,则将根据uri属性将请求转发到http://localhost:8081 。 如果仅路径匹配,则请求将转发到http://localhost:8082

Lets start our gateway server by running mvn spring-boot:run and visit following urls

让我们通过运行mvn spring-boot:run启动我们的网关服务器mvn spring-boot:run并访问以下URL

  • http://localhost:9090/product/version?src=mobile — You will see the message — “Version V1”

    http://localhost:9090/product/version?src=mobile —您将看到消息— “ Version V1”

  • http://localhost:9090/product/version —You will see the message — “Version V2”

    http://localhost:9090/product/version —您将看到消息— “ Version V2”

Congratulations. You just completed the first sample routing for our Api Gateway. We used predicates to route the requests to different versions of a service.

恭喜你您刚刚完成了Api网关的第一个示例路由。 我们使用谓词将请求路由到服务的不同版本。

方案2-限制访问 (Scenario 2- Restricted Access)

As discussed earlier, we need to restrict the access of our write operations including create, update and delete apis of Product Catalog Service. We will do this by updating our route definitions.

如前所述,我们需要限制对写入操作的访问,包括创建,更新和删除Product Catalog Service的api。 我们将通过更新路线定义来做到这一点。

But this time we will to do it in a different way. Spring cloud gateway supports route definition in two ways — configuration files and code. We already used the first option, now we will use the second. Update your GatewayServerApplication.java , the auto generated java file in our gateway server, with the highlighted code.

但是这次我们将以不同的方式来做。 Spring Cloud Gateway通过两种方式支持路由定义-配置文件和代码。 我们已经使用了第一个选项,现在我们将使用第二个选项。 使用突出显示的代码更新您的GatewayServerApplication.java中自动生成的Java文件GatewayServerApplication.java

@SpringBootApplicationpublic class GatewayServerApplication { public static void main(String[] args) {  SpringApplication.run(GatewayServerApplication.class, args); } @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder)  { return builder.routes()  .route("path_route", r -> r.path("/product").and().method("POST", "PUT", "DELETE").and().host("vendor.test-gateway-store.com")  .uri("http://localhost:8081"))  .route("path_route", r -> r.path("/product/**").and().method("GET")  .uri("http://localhost:8082"))  .build(); }}

With the customRouteLocator method, we are again defining two routes. The first route definition says — if a request is received with the path “/product” and the method type is either POST, PUT or DELETE and the host is vendor.test-gateway-store.com then allow the request to be forwarded to http://localhost:8081

使用customRouteLocator 方法,我们再次定义了两条路线。 第一个路由定义是-如果接收到带有路径“ / product”的请求,并且方法类型为POST,PUT或DELETE ,且主机为vendor.test-gateway-store.com,则允许将请求转发至http://localhost:8081

The second route takes care of all the get requests with the pattern /product/** , and forwards them to http://localhost:8082

第二条路由使用/product/**模式处理所有get请求,并将它们转发到http://localhost:8082

If you run your post requests from your local machine, it will fail. If you want them to pass update the host value in the first route as “localhost*”. The get requests will pass for all the different sources.

如果您从本地计算机运行发帖请求,它将失败。 如果希望它们通过,请将第一条路由中的主机值更新为“ localhost *” 获取请求将传递给所有不同的源。

Great! We solved another major issue with the minimal configuration. Two more to go!

大! 我们用最小的配置解决了另一个主要问题。 还有两个!

方案3-监视Apis (Scenario 3 — Monitoring Apis)

This is relatively simpler. To enable gateway metrics, add spring-boot-starter-actuator as a project dependency in our gateway sever application. Gateway Metrics Filter is a global filter and does not need any route configuration. The global filters are special filters that are conditionally applied to all the routes. Lets update the pom.xml to include the actuator dependency —

这是相对简单的。 要启用网关指标,请在我们的网关服务器应用程序中将spring-boot-starter-actuator添加为项目依赖项。 网关度量标准筛选器是全局筛选器,不需要任何路由配置。 全局过滤器是特殊过滤器,有条件地应用于所有路由。 让我们更新pom.xml以包括执行器依赖项-

<project>  ... <dependencies>  ...  <dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-actuator</artifactId>  </dependency></dependencies></project>

Enable the specific actuator views, in src/main/resources/application.properties . This will enable us to view the metrics through browser.

src/main/resources/application.properties启用特定的执行器视图。 这将使我们能够通过浏览器查看指标。

management.endpoints.web.exposure.include=gateway,metrics

Start the gateway server and access the metrics at http://localhost:9090/actuator/metrics/gateway.requests . You can view a response similar to the one below.

启动网关服务器,并访问http://localhost:9090/actuator/metrics/gateway.requests 。 您可以查看与以下响应类似的响应。

{  "name": "gateway.requests",  "description": null,  "baseUnit": "seconds",  "measurements": [    {      "statistic": "COUNT",      "value": 4    },    {      "statistic": "TOTAL_TIME",      "value": 1.754685765    },    {      "statistic": "MAX",      "value": 0.086543555    }  ],  "availableTags": [    {      "tag": "routeUri",      "values": [        "http://localhost:8082",        "http://localhost:8081"      ]    },...  ]}

The above response provides valuable insights including the count of requests, total time taken and maximum time taken for the api response. The above figures reflect the numbers aggregated across all the requests. You can check the specific figures based on routeId, routeUri, outcome, status, httpStatusCode and httpMethod, which are available as filter tags. So if you want to monitor the api on http://localhost:8082 , we can access it through

上面的响应提供了有价值的见解,包括请求计数,花费的总时间以及api响应的最长时间。 上面的数字反映了所有请求中汇总的数字。 您可以根据routeId,routeUri,结果,状态,httpStatusCodehttpMethod(可作为过滤器标签使用)检查特定数字 因此,如果您想监视http://localhost:8082上的api,我们可以通过访问它

http://localhost:9090/actuator/metrics/gateway.requests?tag=routeUri:http://localhost:8082

The above metrics can be easily integrated with Prometheus to create a Grafana dashboard.

可以轻松地将上述指标与Prometheus集成以创建Grafana仪表板

方案4-更新响应标头 (Scenario 4 — Updating Response Header)

So our monitoring results indicate that the get product details api throughput is on compromising side. We will use the basic caching mechanism to improve its performance. We will take help of cache-control response header to limit the hits on the server side. Product details or list are not updated so frequently.

因此,我们的监控结果表明,获取产品详细信息的api吞吐量处于不利的一面。 我们将使用基本的缓存机制来提高其性能。 我们将利用cache-control响应标头来限制服务器端的点击。 产品详细信息或列表更新不是那么频繁。

For our test purpose we will add max-age attribute to it with value of 5 mins. This means the client of this api (get product details) will keep the cache of api results for 5 mins. If the user tries to get the product details with in this period, the cached result will be returned.

出于测试目的,我们将为其添加max-age属性,其值为5分钟。 这意味着此api的客户端(获取产品详细信息)会将api结果的缓存保留5分钟。 如果用户在此期间尝试获取产品详细信息,则将返回缓存的结果。

Lets update our GatewayServerApplication.java

让我们更新我们的GatewayServerApplication.java

@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder builder){ return builder.routes()  .route("path_route", r -> r.path("/product").and().method("POST",  "PUT", "DELETE").and().host("localhost*")  .uri("http://localhost:8081"))  .route("path_route", r -> r.path("/product/**").and().method("GET")  .filters(f -> f.addResponseHeader("Cache-Control", "max-age=300"))  .uri("http://localhost:8082"))  .build();}

We added the required response header with the help of a pre defined filter — Add Response Header filter.

我们在预定义的过滤器(添加响应头过滤器)的帮助下添加了所需的响应头。

Restart the gateway server and try to get the product list. Inspect its response headers and you will find the cache-control header we introduced just now. If you try to add a product now, and refresh, all with in 5 mins, your list will not be updated on the browser side.

重新启动网关服务器,然后尝试获取产品列表。 检查其响应标头,您将找到我们刚才介绍的缓存控制标头。 如果您尝试在5分钟内立即添加产品并刷新所有内容,则列表不会在浏览器端更新。

Bravo! we finished all the scenarios in less than 10 mins.

太棒了! 我们在不到10分钟的时间内完成了所有场景。

学习永无止境 (Learning never stops)

We are able to implement our basic API Gateway server based on Spring Cloud Gateway. The complete source code of the examples, is available at Github. We tried to get a practical insight into the API Gateway pattern but we just scratched the surface, in terms of features.

我们能够实现基于Spring Cloud Gateway的基本API网关服务器 示例的完整源代码可在Github上获得。 我们尝试了 以获得对API网关模式的实用见解,但我们只是从功能上进行了介绍。

We explored few predicates like path, method and host. But the Spring Cloud Gateway provides many more built-in route predicate factories including After/Before/Between DateTime, Cookie, Header, Host, Method, Path, Query, Remote Address and Weight.

我们探索了一些谓词,例如路径,方法宿主。 但是Spring Cloud Gateway提供了更多内置的路由谓词工厂,包括DateTime之后/ Before / Between之间,Cookie,标题,主机,方法,路径,查询,远程地址和权重。

We explored the Add Response filter to implement the cache strategy. Similar to the built-in predicates, there are many other built-in filters too, including Add Request, Add Response, Circuit Breaker, Hystrix, Fallback, Map Request, Prefix Path, Preserve Host, Request Rate Limiter, etc. We can add a custom filter too if the already available set does not suffice the needs.

我们探索了添加响应过滤器以实现缓存策略。 与内置谓词类似,也有很多其他内置过滤器,包括添加请求,添加响应,断路器,Hystrix,回退,映射请求,前缀路径保留主机,请求速率限制器等。 如果已经可用的集合不能满足需要,我们也可以添加自定义过滤器。

The library provides options to cater advance routing needs with Cors Configuration. We already discussed monitoring api performance but the actuator api provides rich set of monitoring options. Do check out the Spring Cloud Gateway documentation to further upgrade your skills with this technology.

该库提供了一些选项,以通过Cors Configuration满足高级路由需求 我们已经讨论了监视api的性能,但是执行器api提供了丰富的监视选项集。 请查看Spring Cloud Gateway文档,以进一步升级使用此技术的技能。

You can browse:1. Next Exercise - Implementing Circuit Breaker 2. Prev Exercise - Implementing Distributed Tracing3. Complete Series - Spring Boot Microservices - Learning through Examples

翻译自: https://medium.com/an-idea/spring-boot-microservices-api-gateway-e9dbcd4bb754


http://www.taodudu.cc/news/show-4021732.html

相关文章:

  • 9.SpringCloud Gateway网关
  • 微服务网关之Springcloud GateWay
  • 微服务api网关_微服务设计api网关模式
  • 浅析API网关——Ocelot[网关]+Consul[服务发现负载均衡]+Polly[服务熔断]+Ids4[服务认证]
  • API网关——zuul
  • 通讯网关 api网关_伟大的api网关迁移
  • Gateway 网关路由、断言、过滤
  • SpringCloud-服务网关
  • 微服务--API网关
  • PostgreSQL下载地址
  • PostgreSQL11.2下载
  • idea下载postgresql的驱动失败Failed to download ,报connect timed out的解决方法
  • PostgreSQL下载安装教程(及PostGIS)
  • Linux 安装PostgreSql
  • PostgreSQL下载及Windows系统安装步骤
  • centos7下载安装postgresql 12详细过程
  • postgresql安装报错
  • PostgreSQL下载与安装
  • PostgreSQL安装(绿色版)
  • PostgreSQL13 安装
  • PostgreSQL修炼之道之PostgreSQL安装与配置(二)
  • PostgreSQL下载安装教程以及官网下载包出现的问题
  • 01Postgresql下载安装和配置
  • PostgreSQL 15.0下载与安装详细保姆教程
  • postgresql下载linux版本
  • PostgreSQL下载与安装(Windows版)
  • Linux PostgreSQL离线下载与安装
  • PostgreSQL下载安装
  • PostgreSQL下载和安装教程
  • PostgreSQL+PostGIS下载和离线安装

Spring Boot微服务API网关相关推荐

  1. 又肝了下微服务 API 网关“金刚”,也是蛮香的~

    " 摘要: 原创出处 http://www.iocoder.cn/Kong/install/ 「芋道源码」欢迎转载,保留摘要,谢谢! 1. 概述 2. 快速安装 3. Kong 控制台 4. ...

  2. Spring Boot 微服务编码风格指南和最佳实践

    文奇摄于世界尽头州立公园 通过多年来使用 Spring Boot 微服务,我编制了一份编码风格指南和最佳实践列表.这份清单并不全面,但我希望您能找到一两点可以借鉴的地方,无论您是新手还是经验丰富的 S ...

  3. vivo亿级微服务 API 网关架构实践

    一.背景介绍 网关作为微服务生态中的重要一环,由于历史原因,中间件团队没有统一的微服务API网关,为此准备技术预研打造一个功能齐全.可用性高的业务网关. 二.技术选型 常见的开源网关按照语言分类有如下 ...

  4. Docker容器及Spring Boot微服务应用

    2019独角兽企业重金招聘Python工程师标准>>> Docker容器及Spring Boot微服务应用 1 什么是Docker 1.1 Docker的出现 问题一:项目实施环境复 ...

  5. Spring Boot微服务间文件返回实现

    Feign接口获取文件流问题_Java_wyazyf的博客-CSDN博客 https://blog.csdn.net/wyazyf/article/details/93200033 Spring Bo ...

  6. vivo 微服务 API 网关架构实践

    一.背景介绍 网关作为微服务生态中的重要一环,由于历史原因,中间件团队没有统一的微服务API网关,为此准备技术预研打造一个功能齐全.可用性高的业务网关. 二.技术选型 常见的开源网关按照语言分类有如下 ...

  7. spring boot 微服务集群 + 注册中心

    spring boot 微服务框架下载地址: https://start.spring.io/ 注册中心 Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进 ...

  8. Spring Boot微服务的黑匣子测试是如此简单

    当我需要进行原型设计,概念验证或在空闲时间使用一些新技术时,开始新项目对于Maven来说总是有点烦人. 不得不说,设置Maven项目并不难,您可以使用Maven原型. 但是原型通常是过时的. 谁想玩旧 ...

  9. api网关选型_微服务 API 网关 APISIX 发布 0.5 版本,达到可用状态

    项目介绍 APISIX (https://github.com/iresty/apisix)  是一个云原生.高性能.可扩展的微服务 API 网关. APISIX 基于 OpenResty 和 etc ...

  10. Kong 1.0 GA 版本正式发布,微服务 API 网关

    Kong 1.0 GA 版本已正式发布,这是一款可扩展.快速且开源的微服务 API 网关,用于管理.保护与连接混合及云原生架构.Kong 运行于全部服务之前,并可以通过插件实现各种扩展,例如身份验证. ...

最新文章

  1. 实际开发中,有时没有异常发生,但是执行结果不是我们期望的情况,需要手动让事务回滚
  2. 阿里转衰!百度没落!字节跳动崛起!未来的互联网是腾讯和字节跳动的世界!这样的言论你相信吗?...
  3. CALayer( 一 )
  4. Android之选项菜单创建
  5. 动态调频DVFS_转
  6. Spring Boot——游戏成就系统设计DEMO
  7. 关于购买kbmMW 的好消息
  8. 解决Chrome谷歌浏览器″Adobe Flash Player 插件已被屏蔽″的问题
  9. 网页中使用的特殊字体(webdings, wingdings 2)
  10. 使用tushare获取A股数据
  11. 大数据时代下的SQL Server第三方负载均衡方案----Moebius测试
  12. macOS中iOS模拟卡顿 ios simulator 高CPU占用解决办法
  13. 音视频基础知识-时间戳的理解
  14. H3C防火墙的登录及管理
  15. Fiddler 抓包工具“测试人员”高频使用方法
  16. LC6936-TWS耳机方案
  17. 面向对象划分--ERP销售订单、生产工单、料号
  18. 公共WiFi有风险,这些风险你都知道吗
  19. 计算机桌面都有说明书,360桌面助手功能使用说明
  20. 大连新成立日本独资企业招聘测试相关职位(PM GL)

热门文章

  1. 线性代数基础知识点回顾与总结(一):行列式与矩阵
  2. 微信分享iOS Universal Link配置说明
  3. 带农历的html日历插件,魔镜日历插件-可生成带农历的日历月历年历-CDR插件
  4. c 语言小游戏坦克大战,C++实现坦克大战小游戏EGE图形界面
  5. 我知道的Activity
  6. python怎么画名字_python 画中国地图怎么把省份名字加上-
  7. linux中PATH环境变量的作用和使用方法
  8. java 密码 星号显示_Java多线程 例子 cmd窗口下 实现输入密码星号显示
  9. Ruby编程语言简介
  10. 华为交换机5855设置ssh