使用Spring Boot和MongoDB构建一个反应式应用程序

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

如果您要处理大量流数据,反应式应用程序可让您更好地扩展。 它们是非阻塞的,并且往往效率更高,因为它们在等待发生事情时不会占用处理能力。

反应系统包含异步I / O。 异步I / O背后的概念很简单:通过回收本来会在等待I / O活动时处于空闲状态的资源来缓解资源利用效率低下的问题。 异步I / O颠倒了I / O处理的常规设计:向客户端通知新数据而不是请求新数据; 这使客户可以在等待时做其他事情。

如果要构建反应式应用程序,则需要它一直到整个数据库都是反应式的。 将阻塞的JDBC驱动程序与Spring WebFlux一起使用,您会对其性能感到失望。 使用反应性NoSQL数据库(例如Cassandra,MongoDB,Couchbase和Redis),其性能将给您留下深刻的印象。

在本教程中,您将学习如何使用Spring Boot,Spring WebFlux和Spring Data创建与NoSQL数据库后端(在本例中为MongoDB)通信的反应式Web服务。

我只是对你说了几句。 让我们越过它们。

如果您已经了解NoSQL和Reactive编程,并且只想看一些代码,请随时跳过前两部分,并从“构建Spring Boot资源服务器”开始。

注意:本系列的第一部分演示了如何将Spring Boot和Spring Data与关系数据库PostgreSQL一起使用。 您可以在此处查看该帖子。

什么是NoSQL?为什么使用MongoDB?

NoSQL是任何非关系数据库的术语。 在关系数据库(例如SQL,MySQL等)中,数据存储在具有强类型且表列之间关系明确的表中。 关系数据库的紧密,定义明确的结构既是优点也是缺点。 这是一个权衡。 NoSQL数据库使该模型爆炸式增长,并提供了其他模型,这些模型可提供更大的灵活性并易于扩展。

扩展的微服务/集群模型为关系数据库带来了很多问题。 它们不是为在多台计算机上运行和保持同步而设计的。 开发NoSQL数据库部分是为了解决此问题。 通常,它们是在考虑群集和水平缩放的情况下构建的。 为了以另一种方式展示这种方式(通常是使用SQL数据库),如果需要更多功能,则必须调整数据库运行所在的服务器的大小。 它几乎是单片的,并且即使当今有现代的虚拟服务器功能,也很难动态地做到这一点。 在Internet规模上,更好的模型是拥有一个灵活的数据库集群,它们可以在数据库之间自动同步,并允许您根据需求增加实例(并在需求减少时减少实例)。 这意味着增加功率并不需要更昂贵的机器。 您可以根据需要简单地添加更多,相对便宜的计算机。

NoSQL数据库的另一个潜在好处是它们的灵活性。 像MongoDB这样的基于文档的NoSQL数据库可以在文档中存储任意数据。 可以将字段动态添加到存储的文档中,而无需增加表迁移的开销。 当然,这并不能解决版本控制的问题,仍然取决于应用程序来处理不断变化的数据结构(并不总是琐碎的),但是至少您并没有与数据库打架。

综上所述,请记住,SQL /关系数据库不会走到任何地方。 它们经过验证,快速且超级可靠。 在某些情况下,它们更便宜,更容易。 例如,对于简单的网站或博客,MySQL很难被击败。 但是即使在企业环境中, 有时您也想要关系数据库强制执行的结构。 如果您有一个相当静态的数据模型并且不需要扩展到Internet规模,则SQL可能是最佳选择。 这些类型的设计注意事项在您深入数据库选择之前值得深思,因为它是新的且浮华的。

我在本教程中使用的是MongoDB,因为一开始它很容易。 如果您使用Spring Data MongoDB,它甚至更容易!

积极反应!

反应性是另一种行话。 感觉就像人们喜欢在聚会和会议上随意表达的那种字眼,只是含糊其词。 就像“存在的”或“ ennui”。 让我们定义它。

如果您看一下Spring WebFlux文档 ,他们会很好地概述什么是反应性

术语“反应性”是指围绕响应变化而构建的编程模型-网络组件响应I / O事件,UI控制器响应鼠标事件等。 从这个意义上说,非阻塞是反应性的,因为随着操作完成或数据可用,我们现在处于响应通知的模式,而不是被阻塞。

因此,反应式意味着:非阻塞,异步且以流处理为中心。

构建一个Spring Boot资源服务器

从GitHub仓库克隆启动项目,并检出start分支:

git clone -b start https://github.com/oktadeveloper/okta-spring-boot-mongo-webflux-example.git

入门项目是一个简单的Spring Boot入门项目,在build.gradle文件中已经具有必需的依赖build.gradle

让我们快速看一下相关性:

compile('org.springframework.boot:spring-boot-starter-webflux')  
compile('org.springframework.boot:spring-boot-starter-data-mongodb-reactive')  
compileOnly('org.projectlombok:lombok')  
compile('de.flapdoodle.embed:de.flapdoodle.embed.mongo')

第一个是针对Spring WebFlux(Spring MVC的响应版本)。 第二个引入了Spring需要的反应性MongoDB依赖关系。 第三个是名为Lombok的项目,该项目使我们免于在Java代码中键入一堆构造函数,getter和setter(您可以在其网页上查看该项目)。 最后一个依赖项是嵌入式的内存MongoDB数据库。 这个数据库非常适合测试,像这样的简单教程,并且不持久。

可以使用简单的Gradle命令运行该应用程序:

./gradlew bootRun

当然,如果您此时运行该应用程序,则不会做太多事情。 Spring Boot将加载,但是还没有定义任何控制器,资源或存储库,因此没有太多事情发生。

为MongoDB定义模型类

为了清楚起见,本教程将与我之前提到的本系列的第一部分并行。 您将要构建一个存储皮划艇类型的简单服务器。 我总是建议首先定义数据结构来开始任何项目。

com.okta.springbootmongo包中创建一个Kayak.java类文件:

package com.okta.springbootmongo;  import lombok.AllArgsConstructor;  
import lombok.Data;  
import lombok.NoArgsConstructor;  
import org.springframework.data.mongodb.core.mapping.Document;  @Document
@Data  
@AllArgsConstructor  
@NoArgsConstructor  
public class Kayak {  private String name;  private String owner;  private Number value;  private String makeModel;  
}

@Document注释与@Entity的NoSQL等效。 它告诉Spring Boot此类正在定义数据模型。 在NoSQL世界中,这意味着创建文档而不是表条目。 其他三个注释是Lombok帮助器,它们自动生成getter,setter和构造函数。

皮划艇文档具有五个属性:名称,所有者,值和类型。 这些会自动映射到MongoDB的适当BSON类型。 什么是BSON类型? 看看有关该主题的MongoDB文档 。 它们是用于将数据保留在MongoDB文档中的二进制序列化类型。 它们定义了可以存储在MongoDB数据库中的原始类型。

将ReactiveMongoRepository添加到您的Spring Boot应用程序

使用@Document批注定义Kayak类可以使Spring Boot知道数据的结构,但实际上并没有提供任何从数据库保存或加载数据的方法。 为此,您需要定义一个存储库。

这样做的代码非常简单。 在com.okta.springbootmongo包中创建一个KayakRepository.java类文件:

package com.okta.springbootmongo;  import org.springframework.data.mongodb.repository.ReactiveMongoRepository;  public interface KayakRepository extends ReactiveMongoRepository<Kayak, Long> {  
}

实际上,这为您提供了从数据库创建,更新,读取和删除文档所需的所有基本方法。 要了解操作方法,请深入研究ReactiveMongoRepository类和其他各种超类,尤其是ReactiveCrudRepository 。 查看ReactiveCrudRepository 的文档以查看已实现的方法。

ReactiveCrudRepository实际上提供了一组基本而完整的CRUD方法。 ReactiveMongoRepository在此基础上构建,以提供一些特定于MongoDB的查询功能。

使用Spring WebFlux实现控制器

添加存储库后,您有足够的能力以编程方式处理数据。 但是,没有定义Web端点。 在前面的教程中,添加REST端点,这是需要的所有是对加@RepositoryRestResource注释到KayakRepository类。 这通过所有CRUD方法为我们自动生成了功能齐全的REST资源。 但是,此快捷方式不适用于Spring WebFlux。 必须明确定义任何公共Web终结点。

添加以下KayakController.java

package com.okta.springbootmongo;  import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.*;  
import reactor.core.publisher.Flux;  @Controller  
@RequestMapping(path = "/kayaks")  
public class KayakController {  private KayakRepository kayakRepository;  public KayakController(KayakRepository kayakRepository) {this.kayakRepository = kayakRepository;}@PostMapping()  public @ResponseBody  Mono<Kayak> addKayak(@RequestBody Kayak kayak) {  return kayakRepository.save(kayak);  }  @GetMapping()  public @ResponseBody  Flux<Kayak> getAllKayaks() {  return kayakRepository.findAll();  }
}

该控制器添加了两个端点:

  • POST /kayaks增加了新的皮划艇
  • GET /kayaks列出所有皮划艇

您还将注意到,该类使用Spring依赖项注入将KayakRepository实例自动KayakRepository到控制器中,并且您将看到如何使用存储库持久化Kayak域类。

此类看起来非常像关系的,阻止的版本。 许多幕后工作使这种情况成为现实。 不用担心,但是,这是100%无反应的非阻塞代码。

测试您的Spring Boot服务器

至此,您已经可以完全运行皮划艇REST资源服务器。 在测试之前,请将以下方法添加到MainApplication类。 只需在应用程序加载时将一些测试数据注入数据库。

@Bean  
ApplicationRunner init(KayakRepository repository) {  Object[][] data = {  {"sea", "Andrew", 300.12, "NDK"},  {"creek", "Andrew", 100.75, "Piranha"},  {"loaner", "Andrew", 75, "Necky"}  };  return args -> {  repository  .deleteAll()  .thenMany(  Flux  .just(data)  .map(array -> {  return new Kayak((String) array[0], (String) array[1], (Number) array[2], (String) array[3]);  })  .flatMap(repository::save)  )  .thenMany(repository.findAll())  .subscribe(kayak -> System.out.println("saving " + kayak.toString()));};  
}

HTTPie是一个很棒的命令行实用工具,它使对资源服务器的请求运行变得容易。 如果未安装HTTPie,请使用brew install httpie进行brew install httpie 。 或前往他们的网站并实现它。 或者只是跟随。

确保您的Spring Boot应用正在运行。 如果不是,请使用./gradlew bootRun启动它。

针对您的资源服务器运行GET请求: http :8080/kayaks ,这是http GET http://localhost:8080/kayaks简写。

您会得到:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
transfer-encoding: chunked
[{"makeModel": "NDK","name": "sea","owner": "Andrew","value": 300.12},{"makeModel": "Piranha","name": "creek","owner": "Andrew","value": 100.75},{"makeModel": "Necky","name": "loaner","owner": "Andrew","value": 75}
]

现在尝试将新的皮划艇过帐到服务器。

http POST :8080/kayaks name="sea2" owner="Andrew" value="500" makeModel="P&H"

您应该看到:

HTTP/1.1 200 OK
Content-Length: 62
Content-Type: application/json;charset=UTF-8
{"makeModel": "P&H","name": "sea2","owner": "Andrew","value": 500
}

如果您重复GET请求http :8080/kayaks ,您将在列表中看到新的皮划艇!

设置安全认证

现在,您需要集成Okta for OAuth 2.0并将基于令牌的身份验证添加到资源服务器。 本部分与本教程第1部分中的部分完全相同,因此,如果您已完成此操作,则只需要您的客户ID,就可以跳至下一部分。

如果尚未注册,请访问developer.okta.com并注册一个免费帐户。 拥有帐户后,通过单击“ 应用程序”顶部菜单项,然后单击“ 添加应用程序”按钮,打开开发人员仪表板并创建OpenID Connect(OIDC)应用程序

反应式应用

选择单页应用程序

反应式应用

默认应用程序设置很好,除了您需要添加登录重定向URIhttps://oidcdebugger.com/debug : https://oidcdebugger.com/debug 。 您将在稍后使用它来检索测试令牌。

注意 :如果要实现像Angular或React这样的前端,则可能需要根据所使用的平台来更新默认的登录重定向URI。 由于本教程仅创建没有前端的资源服务器,因此暂时不重要。 我们所有的资源服务器将要做的就是使用授权服务器验证JSON Web令牌,而无需重定向。

另外,请注意您的客户ID ,稍后您将需要它。

反应式应用

配置您的Spring Boot服务器以进行令牌认证

现在,您需要更新一些项目文件以为OAuth 2.0配置Spring Boot。

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

dependencies {...compile('com.okta.spring:okta-spring-boot-starter:1.1.0')...
}

创建一个名为src/main/resources/application.yml的新配置文件

okta:oauth2:issuer: https://{yourOktaDomain}/oauth2/defaultgroupsClaim: groupsclientId: {yourClientId}

com.okta.springbootmongo包中创建一个SecurityConfiguration.java类:

package com.okta.springbootmongo;import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;@EnableWebFluxSecurity
public class SecurityConfiguration {@Beanpublic SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {http.authorizeExchange().anyExchange().authenticated().and().oauth2ResourceServer().jwt();return http.build();}
}

测试您的受保护服务器

停止您的Spring Boot服务器并使用以下./gradlew bootRun重新启动它: ./gradlew bootRun

从命令行运行一个简单的GET请求。

http :8080/kayaks

您会得到未经授权的401 /。

HTTP/1.1 401 Unauthorized
Cache-Control: no-store
Content-Type: application/json;charset=UTF-8

生成访问令牌

要立即访问服务器,您需要一个有效的访问令牌。 您可以使用OpenID Connect调试器来帮助您完成此任务。 在另一个窗口中,打开oidcdebugger.com 。

  • 授权URIhttps://{yourOktaDomain} /oauth2/default/v1/authorize
  • 重定向URI :不变。 这是您在上面的OIDC应用程序中添加的值。
  • 客户ID :来自您刚创建的OIDC应用程序。
  • 范围openid profile email
  • 状态 :您要通过OAuth重定向过程传递的任何值。 我将其设置为{}
  • Nonce :可以一个人呆着。 Nonce表示“编号已使用一次”,是一种简单的安全措施,用于防止同一请求被多次使用。
  • 响应类型token
  • 响应方式form_post
反应式应用

点击发送请求 。 如果您尚未登录developer.okta.com,则需要登录。如果(可能的话)已经登录,则将为您的登录身份生成令牌。

反应式应用

使用您的访问令牌

您可以通过在Bearer类型的Authorization请求标头中包含令牌来使用令牌。

将令牌存储在shell变量中:

TOKEN=eyJraWQiOiJldjFpay1DS3UzYjJXS3QzSVl1MlJZc3VJSzBBYUl3NkU4SDJfNVJr...

然后使用HTTPie发出GET请求:

http :8080/kayaks "Authorization: Bearer $TOKEN"

请注意上面的双引号。 单引号不起作用,因为shell变量未扩展。

添加基于组的授权

现在,您将通过添加基于组成员身份来控制对特定控制器端点的访问的功能,来使授权方案更加完善。

要在Okta中使用基于组的授权,您需要在访问令牌中添加一个“组”声明。 创建一个Admin组(“ 用户” >“ 组” >“ 添加组” )并将您的用户添加到其中。 您可以使用注册时使用的帐户,也可以创建一个新用户(“ 用户” >“ 添加人” )。 导航到“ API” >“ 授权服务器” ,单击“ 授权服务器”选项卡,然后编辑默认选项卡。 点击索赔标签,然后添加索赔 。 将其命名为“组”,并将其包含在访问令牌中。 将值类型设置为“ Groups”,并将过滤器设置为.*的正则表达式。

声明包含用户分配到的组。 您用来登录developer.okta.com网站的默认用户也将是“所有人”组和“管理员”组的成员。

还需要更新SecurityConfiguration类以使用基于组的授权。 更新Java文件以匹配以下内容:

package com.okta.springbootmongo;import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {@Beanpublic SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {http.authorizeExchange().pathMatchers(HttpMethod.POST, "/kayaks/**").hasAuthority("Admin").anyExchange().authenticated().and().oauth2ResourceServer().jwt();return http.build();}
}

用简单的英语来说,这告诉Spring Boot要求对/kayak端点的任何POST都具有组成员身份Admin ,对于所有其他请求,仅需要有效的JWT。

您的基于组的授权策略由以下两行定义:

.pathMatchers(HttpMethod.POST, "/kayaks/**").hasAuthority("Admin")  
.anyExchange().authenticated()

有关更多信息,请参阅ServerHttpSecurity类的文档 。

您可能想知道为什么它说hasAuthority()而不是hasRole()hasGroup() 。 这是因为授权是Spring调用服务器发送的文本字符串以表示权限成员身份的方式,无论是角色还是组。 hasRole()假定角色采用特定格式:“ ROLE_ADMIN”。 可以重写此方法,但是hasAuthority()是直接使用授权字符串的简单方法。 没有hasGroup()方法,因为前两个示例(如果未明确说明)涵盖了该用例。

创建一个非管理员用户

要测试基于组的授权方案,您需要一个不是管理员的用户。 转到developer.okta.com仪表板。

从顶部菜单中,选择“ 用户” >“ 人员” 。 单击添加人按钮。

给用户一个名字姓氏用户名 (也将是主要电子邮件 )。 值无关紧要,并且您将不必检查电子邮件。 您只需要知道电子邮件地址/用户名和密码,即可在一分钟内登录Okta。

密码 :将下拉菜单更改为“ 由管理员设置”

为用户分配密码。

点击保存

您刚刚创建的用户不是Admin组的成员,而是默认组Everyone的成员。

基于测试组的授权

注销您的Okta开发人员仪表板。

返回OIDC调试器并生成一个新令牌。

这次,以新的非管理员用户身份登录。 系统会要求您选择一个安全问题,然后将您重定向到https://oidcdebugger.com/debug页面,您可以在其中复制令牌。

如果愿意,可以转到jsonwebtoken.io并解码新令牌。 在有效内容中, 声明将显示用户的电子邮件/用户名,而声明将仅显示“ 所有人”组。

{"sub": "test@gmail.com","groups": ["Everyone"]
}

根据许可方案,该用户应该能够列出所有皮划艇,但不能添加新的皮划艇。

请记住,将令牌存储在shell脚本中,如下所示:

TOKEN=eyJraWQiOiI4UlE5REJGVUJOTnJER0VGaEExekd6bWJqREpSYTRTT1lhaGpsM3d4...

发出GET请求以列出所有皮划艇:

http :8080/kayaks "Authorization: Bearer $TOKEN"HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
...[{"makeModel": "NDK","name": "sea","owner": "Andrew","value": 300.12},{"makeModel": "Necky","name": "loaner","owner": "Andrew","value": 75},{"makeModel": "Piranha","name": "creek","owner": "Andrew","value": 100.75}
]

尝试使用非管理员用户令牌添加新的皮划艇:

http POST :8080/kayaks "Authorization: Bearer $TOKEN" name="sea2" owner="Andrew" value="500" makeModel="P&H"

您将被拒绝!

HTTP/1.1 403 Forbidden
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
...

现在,注销developer.okta.com,并使用OIDC Debugger生成一个新令牌。 这次使用您原来的管理员帐户重新登录。

将新令牌存储在shell变量TOKEN

运行POST请求:

http POST :8080/kayaks "Authorization: Bearer $TOKEN" name="sea2" owner="Andrew" value="500" makeModel="P&H"

AM! 💥

HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
...
{"makeModel": "P&H","name": "sea2","owner": "Andrew","value": 500
}

一切顺利,已通过身份验证

而已! 在本教程中,您使用Spring WebFlux创建了一个Spring Boot应用程序,使用嵌入式MongoDB数据库来持久化模型类,并向其中添加了资源服务器。 之后,我向您展示了如何使用Okta和OAuth 2.0添加JWT令牌身份验证。 最后,您了解了如何使用Okta和Spring Security将基于组的授权添加到控制器中的特定端点。

如果您想查看这个完整的项目,可以在oktadeveloper / okta-spring-boot-mongo-webflux-example上的GitHub上找到该仓库 。

如果还没有,请查看本系列的第1部分: 使用PostgreSQL使用Spring Boot和JPA构建基本应用程序 。 它是同一个应用程序,但是使用了更传统的关系数据库和Spring MVC样式的阻止Web服务器。

了解有关Spring Boot,MongoDB和安全用户管理的更多信息

如果您想了解有关Spring Boot,Spring Security或Okta的更多信息,请查看以下任何出色的教程:

  • 使用Spring WebFlux构建反应性API
  • Spring Boot,OAuth 2.0和Okta入门
  • 15分钟内将单一登录添加到您的Spring Boot Web App
  • 使用多重身份验证保护您的Spring Boot应用程序安全
  • 使用Spring Boot和GraphQL构建安全的API

以下是一些来自Spring的优秀资源:

  • 对Spring Data做出反应
  • OAuth2 WebFlux文档
  • 构建反应式RESTful Web服务
  • Spring WebFlux文档

如果您喜欢这篇文章,您可能会喜欢我们发布的其他文章。 在Twitter上关注@oktadev ,并订阅我们的YouTube频道以获取更多有趣的教程。

“使用Spring Boot和MongoDB构建反应性应用程序”最初于2019年2月21日发布在Okta开发人员博客上。

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

翻译自: https://www.javacodegeeks.com/2019/03/build-reactive-app-spring-boot-mongodb.html

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

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

相关文章

c语言 freopen txt_C语言:freopen函数

当我们求解acm题目时&#xff0c;通常在设计好算法和程序后&#xff0c;要在调试环境(例如VC等)中运行程序&#xff0c;输入测试数据&#xff0c;当能得到正确运行结果后&#xff0c;才将程序提交到oj中。但由于调试往往不能一次成功&#xff0c;每次运行时&#xff0c;都要重新…

工业交换机如何判断性能的好坏呢?

当前的智能控制系统和工厂自动化系统常常采用工业交换机完成工业控制任务&#xff0c;工业以太网的应用非常普及。对于工业交换机的选购&#xff0c;把握工业交换机的主要性能指标是关键。那么&#xff0c;工业交换机如何判断性能的好坏呢&#xff1f;接下来就由飞畅科技的小编…

【渝粤教育】国家开放大学2018年春季 建筑结构基础 参考试题

科目编号&#xff1a;8 -6-6- 6 座位号 2017-2018学年度第二学期期末考试 建筑结构基础 试题 2018年 7 月 一、单选题&#xff08;本大题共10小题&#xff0c;每小题4分&#xff0c;共计40分&#xff09; &#xff08;★请考生务必将答案填入到下面对应序号的答题框中★&#…

zune自搭虚拟服务器离线升级,Zune 30g 固件更新至 3.3 记录

换成64位Win7后Zune的桌面管理器木有了&#xff0c;而64位版的Zune 1.3桌面安装麻烦死个人&#xff0c;各大论坛的115下载连接无一例外的都断链了&#xff0c;无奈只好把Zune升级至最新的3.3。升级记录&#xff1a;1. 在Zune官网 http://www.zune.net/zh-CH 下载最新版的桌面管…

21秋期末考试土力学与地基基础10445k1

1、严寒地区的粘土砖强度不会受到地基土中含水量的影响。&#xff08;2.5 分&#xff09; A&#xff0e;错误 B&#xff0e;正确 2、粘性土根据其塑性指数的不同&#xff0c;又可分为粘土和粉质粘土。&#xff08;2.5 分&#xff09; A&#xff0e;错误 B&#xff0e;正确 3、任…

工业交换机芯片选择需要注意什么事项呢?

相信不少工业级交换机品牌&#xff0c;在其工业交换机机内的芯片选择上一定很慎重&#xff0c;因为工业交换价的芯片将影响到其以后的使用&#xff0c;工业交换机常用的芯片有Marvell和Broadcom平台。那么&#xff0c;工业交换机芯片选择要注意什么呢&#xff1f;接下来就由飞畅…

21秋期末考试建设工程法规10221k1

1、当事人既约定违约金&#xff0c;又约定定金的&#xff0c;一方违约时&#xff0c;这两种违约责任&#xff08;  &#xff09;。&#xff08;1 分&#xff09; A&#xff0e;可合并使用 B&#xff0e;适用数值较小者 C&#xff0e;适用数值较大者 D&#xff0e;只能选择其一…

nginx mysql5.7_Centos7+Php7+Mysql5.7+Nginx源码安装实战部署手册

本文以Centos 7.1Php 7.1.3Mysql5.7.17为例,介绍Centos7Php7Mysql5.7Nginx 1.10.3源码安装实战部署的过程。一.准备工作软件获取二.安装Mysql安装目录/usr/local/mysql数据库目录/data/mysqldb1.安装编译工具yum -y install cmake gcc-c ncurses-devel perl-Data-Dumper boost …

【渝粤教育】21秋期末考试互联网营销概论10092k2

1、品牌最基本的含义是品牌代表着特定的&#xff08;&#xff09;。&#xff08;2 分&#xff09; A&#xff0e;消费者类型 B&#xff0e;商品属性 C&#xff0e;利益 D&#xff0e;文化 2、网上竞价模式主要有&#xff08; &#xff09;。&#xff08;2 分&#xff09; A&…

工业路由器和工业交换机的区别介绍

现在是信息时代,随着时代的进步,互联网是人们生活不可或缺的一部分。通常由许多不同类型的计算机网络相互连接而成。如果几个计算机网络在物理上连接在一起,它们之间并不能进行沟通,那么这种“互连”没有实际意义。所以在谈到“互连”时,就已经暗示这些相互连接的计算机可以进行…

JAX-RS和OpenAPI对Hypermedia API的支持:任重而道远

或早或晚&#xff0c;大多数积极使用REST&#xff08;ful&#xff09; Web服务和API的开发人员都偶然发现了这种真正的外星事物&#xff0c;即HATEOAS &#xff1a; 超文本作为应用程序状态的引擎 。 对HATEOAS是什么以及它与REST的关系的好奇最终将导致发现Richardson成熟度模…

【渝粤教育】21秋期末考试大学英语210262k2

1、He has_______since three days ago.&#xff08;2 分&#xff09; A&#xff0e;gone away B&#xff0e;gone C&#xff0e;left D&#xff0e;been away 2、What an interesting book! I don’t want to .&#xff08;2 分&#xff09; A&#xff0e;give to it B&#x…

【渝粤教育】21秋期末考试建筑工程计量与计价10517k1

1、施工排水降水中成井的计量单位是&#xff08; &#xff09;&#xff08;1 分&#xff09; A&#xff0e;天 B&#xff0e;m C&#xff0e;台次 D&#xff0e;昼夜 2、按广东省18定额规定&#xff0c;天棚装饰高度超过&#xff08;&#xff09;&#xff0c;可计算满堂脚手架。…

工业以太网交换机的光口和电口有什么区别?

对于从事安防传输设备行业的朋友们来说&#xff0c;相信大家对工业以太网交换机应该都不陌生。客户购买工业以太网交换机时&#xff0c;很多客户都会要几光几电的交换机&#xff0c;最近也接到不少客户的电话&#xff0c;都会询问工业以太网交换机的电口和光口有什么区别&#…

【渝粤教育】21秋期末考试混凝土结构10515k1

21秋期末考试混凝土结构10515k1 1、钢筋混凝土轴心受压构件&#xff0c;稳定系数是为了考虑&#xff1a; &#xff08; &#xff09;。&#xff08;3 分&#xff09; A&#xff0e;附加偏心距的影响 B&#xff0e;附加弯矩的影响 C&#xff0e;剪力的影响 D&#xff0e;承载力的…

工业以太网交换机与网络交换机的区别

工业以太网交换机与商用交换机在数据交换功能上基本一致&#xff0c;但在设计上以及在元器件的选用上&#xff0c;产品的强度和适用性方面更能满足工业现场的需要。此外在模块扩展方面也表现的比商用交换机更为灵活&#xff1a;有多种光口和电口可供选配。在材质的选用、产品的…

【渝粤教育】国家开放大学2018年春季 0004-21T有机合成单元反应 参考试题

科目编号&#xff1a;0004 座位号&#xff1a; 2017-2018学年度第二学期期末考试 有机合成单元过程 2018年6月 一、选择题&#xff08;每小题3分&#xff0c;共45分) 1、分子结构中具有&#xff08; )官能团的有机化合物&#xff0c;通常称之为羧酸。 —NO2 B.—COOH C.—CH…

【渝粤教育】国家开放大学2018年春季 0014-22T秘书学(一) 参考试题

试卷编号&#xff1a;0014 座位号 2017—2018学年度第二学期期末考试 秘书学&#xff08;一&#xff09; 试 题 2018年7月 1&#xff0e;秘书环境 2. 公共关系3. 辅助决策4. 协调关系1&#xff0e;秘书事务的内容有&#xff08; &#xff09; A&#xff0e;接打电话 B.车辆管…

mysql 内存溢出_mysql - MySQL在非常大的表上计算性能 - 堆栈内存溢出

我在Innodb中有一个表格&#xff0c;其中有超过1亿行。我必须知道外键 1时是否有超过5000行。我不需要确切的数字。我做了一些测试&#xff1a;> 16 seconds > 16秒中> 16 seconds > 16秒中> 0.6 seconds > 0.6秒我的网络和治疗时间会更长一些&#xff0c;但…

【渝粤教育】国家开放大学2018年春季 0045-22T烹饪原料学(1) 参考试题

编号&#xff1a;0045 座位号 2017&#xff5e;2018学年度第二学期期末考试 烹饪原料学&#xff08;1&#xff09;试题 2018年5月 一、名词解释&#xff08;本大题共4小题&#xff0c;每题5分&#xff0c;共20分&#xff09;。 腌腊制品 鱼翅 调味原料 香辛料 二、单项选…