Spring Cloud和云计算没有关系,只是一个基于Spring Boot的快速构建分布式系统的工具集。

一 Spring Cloud特点

# 约定优于配置

# 开箱即用,快速启动

# 适用于各种环境,可以部署在PC server或者 云环境

# 轻量级的组件

# 组件的支持很丰富,功能齐全

# 选型中立

二 服务提供者和服务消费者

三 服务发现和注册

为什么需要服务注册与发现

# 服务重启或者升级后IP地址变化

# 水平伸缩后服务实例的变化

# 同一个节点运行多个服务

所以需要一种注册机制,帮助我们去获取响应。

核心机制:

将实例的信息注册到注册中心

调用者通过注册中心查找服务

调用者获取服务实例列表

调用者通过负载均衡通信

3.1 基本流程

首先:服务消费者和服务注册者向服务发现组件注册

其次:服务消费者要调用的时候会从服务发现组件中进行查询

需求:

# 每一个服务实例都会在启动的时候通过HTTP/REST或者Thrift等方式发布远程API

# 服务端实例的具体数量及位置会发生动态变化

# 虚拟机与容器通常会被分配动态IP地址

3.2 服务发现组件的功能

# 服务注册表: 是一个记录当前可用服务实例的网络信息的数据库,是服务发现机制的核心。服务注册表提供查询API和管理API,使用API 获得可用的服务实例,使用管理API实现注册和注销。

# 服务注册

# 健康检查

3.3 服务发现的方式

3.3.1 客户端发现

它的主要特点是客户端决定服务实例的网络位置,并且对请求进行负载均衡。客户端查询服务注册表(可用服务实例数据库),使用负载均衡算法选择一个实例,并发出请求。典型代表Eureka或者ZK

客户端发现模式的优缺点

优点:

不需要很多的网络跳转

缺点:

客户端和服务注册表耦合

需要为应用程序每一种编程语言、框架等建立客户端发现逻辑,比如 Netflix Prana就为非JVM客户端提供一套基于HTTP代理服务发现方案

# 服务器端发现

向某一服务发送请求,客户端会通过向运行位置已知的路由器或者负载均衡器发送请求。他们会查询服务注册表,并向可用的服务实例转发该请求。典型代表Consul + Nginx

服务器端发现模式优缺点:

优点:

客户端无需实现发现功能,只需要向路由器或者负载均衡器发送请求即可

缺点:

除非成为云环境的一部分,否则该路由机制必须作为另一系统组件进行安装与配置。为实现可用性和一定的接入能力,还需要为其配置一定数量的副本。

相较于客户端发现,服务器端发现机制需要更多的网络跳转。

3.4 服务发现组件Eureka

3.4.1 什么是Eureka

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。Spring Cloud将它集成在其他子项目spring-cloud-netflix中,以实现spring cloud服务发现功能。

3.4.2 Eureka原理

先需要明白AWS几个概念:

Region: AWS云服务在全球不同的地方都有数据中心,比如北美、南美和欧洲亚洲等。与此对应,根据地理位置我们把某个地区的基础设施服务集合称为一个区域。不同区域之间是相互独立的。说白了就类似于不同地方的机房。

Available Zone: 基于容灾背景提出,简单而言,就是相同region区域不同的机房

# 首先是服务注册到Eureka

# 每30s发送心跳检测重新进行租约,如果客户端不能多次更新租约,它将在90s内从服务器注册中心移除。

# 注册信息和更新会被复制到其他Eureka 节点,来自任何区域的客户端科可以查找到注册中心信息,每30s发生一次复制来定位他们的服务,并进行远程调用

# 客户端还可以缓存一些服务实例信息,所以即使Eureka全挂掉,客户端也是可以定位到服务地址的

3.4.3 搭建Euraka Server

首先:搭建parent项目

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<modules>

<module>microservice-consumer</module>

<module>microservice-provider</module>

<module>microservice-discovery-eureka</module>

</modules>

<groupId>com.microservice</groupId>

<artifactId>microservice</artifactId>

<version>1.0-SNAPSHOT</version>

<packaging>pom</packaging>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.6.RELEASE</version>

</parent>

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Dalston.SR3</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-config</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-eureka</artifactId>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.44</version>

</dependency>

</dependencies>

<build>

<finalName>${project.artifactId}</finalName>

<plugins>

<!--资源文件拷贝插件 -->

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-resources-plugin</artifactId>

<configuration>

<encoding>UTF-8</encoding>

</configuration>

</plugin>

<!--java编译插件 -->

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<configuration>

<source>1.8</source>

<target>1.8</target>

<encoding>UTF-8</encoding>

</configuration>

</plugin>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

<pluginManagement>

<plugins>

<!--配置tomcat插件 -->

<plugin>

<groupId>org.apache.tomcat.maven</groupId>

<artifactId>tomcat7-maven-plugin</artifactId>

<version>2.2</version>

</plugin>

</plugins>

</pluginManagement>

</build>

</project>

其次:搭建Euraka Server

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<packaging>war</packaging>

<parent>

<artifactId>microservice</artifactId>

<groupId>com.microservice</groupId>

<version>1.0-SNAPSHOT</version>

</parent>

<artifactId>microservice-discovery-eureka</artifactId>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-eureka-server</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-security</artifactId>

</dependency>

</dependencies>

</project>

然后:在application.xml中配置application.yml文件

security:

basic:

enabled: true

user:

name: user

password: password

server:

port: 8761

eureka:

client:

register-with-eureka: false

fetch-registry: false

service-url:

defaultZone:http://user:password@localhost:8761/eureka

最后:创建EurekaApplication,并添加@SpringBootApplication

@EnableEurekaServer

public class EurakaApplication{

public static void main(String[] args) throws Exception {

SpringApplication.run(EurakaApplication.class, args);

}

}

就可以启动Eureka Server了

3.4 将微服务注册到Eureka上

首先:确认当前maven环境下是否引入了Eureka相关的配置,并且添加如下依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

其次:在微服务启动类上添加@EnableEurekaClient注解,使得他成为一个Eureka Client,在启动的 时候就向Eureka Server注册。

然后:在微服务的应用程序中application.yml配置文件中,我们不要添加如下配置,因为这表示是服务器,客户端我们是需要向Eureka注册的

eureka:

client:

register-with-eureka: false

fetch-registry: false

应该可以的配置有健康检查和路径配置

eureka:

client:

healthcheck:

enabled: true

service-url:

defaultZone:http://nicky:123abcABC@localhost:8761/eureka

最后:在启动类添加@EnableEurekaClient注解,表示这个类可以作为Eureka 客户端,启动之后可以向Eureka注册

@SpringBootApplication

@EnableEurekaClient

public class UserServiceRunner{

public static void main(String[] args) throws Exception {

SpringApplication.run(UserServiceRunner.class, args);

}

}

3.5 Eureka配置项

eureka.client.allow-redirects:是否允许重定向Eureka客户端请求到其他或者备份服务器,默认为fasle

eureka.client.eureka-connection-idle-timeout-seconds:HTTP连接到eureka服务器可以在关闭之前保持空闲的时间(几秒钟)。

eureka.client.eureka-server-connect-timeout-seconds:表示连接Eureka服务器,等待多长时间算超时

eureka.client.eureka-server-port: Eureka Server端口

eureka.client.eureka-server-d-n-s-name:获取要查询的DNS名称以获得eureka服务器的列表。

eureka.client.eureka-server-read-timeout-seconds:示在从eureka服务器读取数据之前需要等待多长时间(以秒为单位)

eureka.client.eureka-server-total-connections:从eureka客户端到所有eureka服务器的所允许连接总数。

eureka.client.eureka-server-total-connections-per-host:设置每一个主机所允许的到Eureka Server连接的数量

eureka.client.fetch-registry: 是否允许客户端向Eureka 注册表获取信息,一般服务器为设置为false,客户端设置为true

eureka.client.register-with-eureka:是否允许向Eureka Server注册信息,默认true,如果是服务器端,应该设置为false

eureka.client.fetch-remote-regions-registry:逗号分隔的区域列表,用于获取eureka注册信息

eureka.client.g-zip-content:从服务器端获取数据是否需要压缩

eureka.client.prefer-same-zone-eureka: 是否优先使选择相同Zone的实例,默认为true

eureka.client.registry-fetch-interval-seconds:多长时间从Eureka Server注册表获取一次数据,默认30s

eureka.client.service-url:可用区域映射,列出完全合格的url与eureka服务器通信。每个值可以是一个URL,也可以是一个逗号分隔的替代位置列表。

eureka.dashboard.enabled: 是否启用Eureka首页,默认为true

eureka.dashboard.path: 默认为/

eureka.instance.appname:在eureka注册的应用程序的名称。

eureka.instance.app-group-name:在eureka注册的应用程序的组名称

eureka.instance.health-check-url: 健康检查绝对路径

eureka.instance.health-check-url-path:健康检查相对路径

eureka.instance.hostname:设置主机名

eureka.instance.instance-id:设置注册实例的id

eureka.instance.lease-expiration-duration-in-seconds:设置多长时间意味着租约到期,默认90

eureka.instance.lease-renewal-interval-in-seconds:表示Eureka客户端需要发送心跳到eureka服务器的频率(以秒为单位),以表明它仍然存在。指定的期间内如果没有收到心跳leaseExpirationDurationInSeconds

eureka.instance.metadata-map:可以设置元数据

eureka.instance.prefer-ip-address: 实例名以IP,但是建议hostname,默认为false

四 负载均衡

4.1 Ribbon的介绍和架构

实现负载均衡,我们可以通过服务器端和客户端做负载均衡。服务器端做负载均衡,比如可以使用Nginx。而客户端做负载均衡,就是客户端有一个组件,知道有哪些可用的微服务,实现一个负载均衡的算法。

Ribbon工作流程主要分为两步:

第一:先选择Eureka Server,优先选择在同一个Zone且负载较少的Server;

第二:再根据用户指定的策略,再从server取到的服务注册列表中选择一个地址。其中Ribbon提供了很多种策略,例如轮询round bin,随机Random,根据响应时间加权。

4.2 使用Ribbon进行负载均衡

4.2.1 基本用法

要使用Ribbon进行负载均衡,那么就需要引入对应的依赖,如果已经因如果Eureka的依赖,那么就不需要再次引入Ribbon的依赖了。

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-ribbon</artifactId>

</dependency>

然后在启动类上加上注解@LoadBalanced,则负载均衡生效。

@SpringBootApplication

@EnableEurekaClient

public classMovieServiceRibbonRunner {

@Bean

@LoadBalanced

public RestTemplaterestTemplate(){

return new RestTemplate();

}

public static void main(String[] args) {

SpringApplication.run(MovieServiceRibbonRunner.class, args);

}

}

我们可以修改application.yml文件的instance_id属性:

eureka:

client:

healthcheck:

enabled: true

service-url:

defaultZone:http://nicky:123abcABC@localhost:8761/eureka

instance:

instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}

在消费者Controller中,访问虚拟的ip,即我们微服务的名称

@RestController

public class MovieController {

@Autowired

private RestTemplate restTemplate;

@GetMapping("/movie/{id}")

public User findById(@PathVariable Long id) {

returnthis.restTemplate.getForObject("http://microservice-provider-user/user/"+id, User.class);

}

}

最后启动两个服务提供者实例,可以修改端口实现。

4.2.2 通过代码自定义配置Ribbon

首先,该类需要加上@Configuration注解,但是注意,如果加上这个注解,他就不能包含在注解@ComponentScan或者@SpringBootApplication所指定包扫描路径。

@Configuration

public classRibbonTestConfiguration {

@Autowired

IClientConfig config;

@Bean

public IRuleribbonRule(IClientConfig config){

return new RandomRule();

}

}

其次:在启动类上加上@RibbonClient注解,指定名称和configuration文件类

@SpringBootApplication

@EnableEurekaClient

@RibbonClient(name="microservice-provider-user",configuration=RibbonTestConfiguration.class)

public classMovieServiceRunner {

@Bean

@LoadBalanced

public RestTemplaterestTemplate(){

return new RestTemplate();

}

public static void main(String[] args) {

SpringApplication.run(MovieServiceRunner.class, args);

}

}

4.2.3 通过配置文件自定义Ribbon

即我们可以通过yml或者properties配置文件,进行配置,然后使用我们配置的选项。

注意:这里有些优先级的顺序问题:

配置文件定义的优先级大于通过使用Java代码@RibbonClient的优先级大于使用spring默认的优先级

支持以下属性:

NFLoadBalancerClassName:应该实现 ILoadBalancer

NFLoadBalancerRuleClassName:应该实现 IRule

NFLoadBalancerPingClassName:应该实现IPing

NIWSServerListClassName:应该实现 ServerList

NIWSServerListFilterClassName:应该实现 ServerListFilter

application.yml中配置如下:

microservice-provider-user:

ribbon:

NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule

五 Feign (声明式的REST Client)

5.1 简介及基础使用

Feign是一个声明式的web服务客户端,它使得写web服务客户端更加容易。使用Feign创建一个接口并对其进行注解。它具有可插拔的注解支持,包括Feign自己的注解以及jax-rs注释。Feign还支持可插拔的的编码器和解码器。Spring Cloud增加了对Spring MVC注解的支持,并使用了在Spring Web中默认使用的相同的HttpMessageConverters。Spring Cloud集成了Ribbon和灵感,在使用时提供了负载均衡的http客户端。

加入Feign的依赖到Maven

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-feign</artifactId>

</dependency>

然后创建接口,并且添加注解@EnableFeignClients

@SpringBootApplication

@EnableEurekaClient

@EnableFeignClients

public classMovieServiceRunner {

public static void main(String[] args) {

SpringApplication.run(MovieServiceRunner.class, args);

}

}

写真正的接口去调用其他微服务,以供本应用调用

创建接口:

首先在接口加上注解@FeignClient,指定需要调用微服务名字

其次:如果启动的时候,提示Http Method不正确我们需要使用以前的老的注解,即:

@RequestMapping(method= RequestMethod.GET, value = "/user/{id}"),而不能使用:

@GetMapping("/user/{id}")

然后:如果提示PathVariableannotation was empty on param 0,那么我们就需要:

还有就是:微服务提供方和消费者两边的HTTP 方法必须最好一致,如果一边是GET 请求,另外一边是POST请求,就会报错。而且如果传递的是一个负载对象,即使指定的是GET请求,也会作为POST请求,一般做法就是不传递对象,而是传递单个参数

比如@ReqquestParam(“name”) String name,@ReqquestParam(“age”) int age之类的

public UserfindById(@PathVariable("id") Long id); 而不是:

public UserfindById(@PathVariable Long id); 就可以

这相当于是Feign的坑吧

@FeignClient("microservice-provider-user")

public interface UserFeignClient {

@GetMapping("/user/{id}")

public User findById(@PathVariable Long id);

}

然后在其他类中就可以调用了:

@RestController

public class MovieController {

@Autowired

private UserFeignClient userFeignClient;

@GetMapping("/movie/{id}")

public User findById(@PathVariable Long id) {

return userFeignClient.findById(id);

}

}

5.2 覆写Feign的配置

Spring Cloud允许你完全控制Feign 客户端通过声明一些额外的注解,即@FeignClient(name = "stores",configuration = FooConfiguration.class)

一般来说,我们不需要使用在自定义的FooConfiguration上使用@Configuration组件,如果要使用我们需要把它从包含@ComponentScan或者@SpringBootApplication注解所扫描的包中排除掉。和Ribbon类似。

假设我们现在定义了一个Configuration1这个类,使用feign默认的契约,而不是使用SpringMvcContract,即:

@Configuration

public class Configuration1 {

@Bean

public ContractfeignContract() {

return newfeign.Contract.Default();

}

}

然后在Feign的接口处,指定@FeignClient的configuration,重写配置,使用刚才定义的Configuration1,即:

@FeignClient(name="microservice-provider-user",configuration=Configuration1.class)

public interface UserFeignClient {

@GetMapping("/user/{id}")

public User findById(@PathVariable("id") Long id);

}

但是在这儿我们依然用的是SpringMVC的注解,GetMapping,这里虽然没有报错,但是启动的时候就会报错了。比如java.lang.IllegalStateException: MethodfindById not annotated with HTTP method type (ex. GET, POST)

所以,接口处我们应该替换为Feign自己的注解。

@FeignClient(name="microservice-provider-user",configuration=Configuration1.class)

public interface UserFeignClient {

@RequestLine("GET /user/{id}")

public User findById(@Param("id") Long id);

}

Feign支持请求响应GZIP压缩:

feign.compression.request.enabled=true

feign.compression.response.enabled=true

5.3 feign的日志

Feign的默认日志级别是DEBUG 级别。

@Bean

Logger.Level feignLoggerLevel(){

return Logger.Level.FULL;

}

六 常见问题解决方案

6.1 Eureka环境以及cloud配置

Eureka可以运行AWS环境和非AWS环境上,Eureka也可以以测试环境和生产环境运行。

如果需要运行在AWS环境上,则需要通过-Deureka.datacenter=cloud指定运行在AWS上,在yml中我们可以通过eureka.datacenter:cloud指定。

eureka.datacenter:cloud

如果需要运行在测试或者生产环境,我们需要通过-Deureka.environment来指定。如果指定测试环境eureka.environment: test, 如果运行在生产环境,则指定eureka.environment:product

6.2 自我保护提示

6.3 Eureka注册服务慢的问题如何解决

作为实例还涉及到与注册中心的周期性心跳,默认持续时间为30秒(通过serviceUrl)。在实例、服务器、客户端都在本地缓存中具有相同的元数据之前,服务不可用于客户端发现(所以可能需要3次心跳)。你可以使用eureka.instance.leaseRenewalIntervalInSeconds配置,这将加快客户端连接到其他服务的过程。

在生产中,最好坚持使用默认值,因为在服务器内部有一些计算,他们对续约做出假设。

6.4如何解决Eureka Server不踢出已关停的节点的问题

服务器端:

# 关闭自我保护

eureka.server.enable-self-preservation:false

# 缩小清理间隔(单位毫秒,默认是60*1000)

eureka.server.eviction-interval-timer-in-ms:  5000

客户端:

开启健康检查(需要spring-boot-starter-actuator依赖)

eureka.client.healthcheck.enabled= true

租期更新时间间隔(默认30秒)

eureka.instance.lease-renewal-interval-in-seconds=10

租期到期时间(默认90秒)

eureka.instance.lease-expiration-duration-in-seconds=30

6.5 Eureka HA配置(假设三个节点)

6.5.1 在hosts文件中加入如下配置

127.0.0.1  peer1

127.0.0.1  peer2

127.0.0.1  peer3

6.5.2 在application.yml中加入以下配置

---

spring:

profiles: peer1

application:

name: EUREKA-HA

server:

port: 8761

eureka:

instance:

hostname: peer1

client:

serviceUrl:

defaultZone:http://peer2:8762/eureka/,http://peer3:8763/eureka/

---

spring:

profiles: peer2

application:

name: EUREKA-HA

server:

port: 8762

eureka:

instance:

hostname: peer2

client:

serviceUrl:

defaultZone:http://peer1:8761/eureka/,http://peer3:8763/eureka/

---

spring:

profiles: peer3

application:

name: EUREKA-HA

server:

port: 8763

eureka:

instance:

hostname: peer3

client:

serviceUrl:

defaultZone:http://peer1:8761/eureka/,http://peer2:8762/eureka/

服务发现和注册和Eureka相关推荐

  1. 微服务发现与注册之Eureka源码分析

    作者:陌北有棵树,Java人,架构师社区合伙人! [一]微服务之服务发现概述 关于微服务,近年来可谓是大火,业界也吹刮着一种实践微服务的风潮.本人有幸在去年参与到一个向微服务过渡的产品,再结合自己所学 ...

  2. 微服务系列:服务发现与注册-----Eureka(面试突击!你想了解的Eureka都在这里.持续更新中......)

    1.什么是落地SOA(面向服务架构)? SOA面向服务架构,是一种架构思想,是跨语言和平台的.SOA宗旨简单明了,根据项目服务完成架构搭建,以服务为基准点完成组件化和模块化.提供服务是项目的基本内容, ...

  3. 我是服务的执政官-服务发现和注册工具consul简介

    服务发现和注册 我们有了两个服务.服务A的IP地址是192.168.0.1,端口9001,服务B的IP地址192.168.0.2,端口9002.我们的客户端需要调用服务A和服务B,我们只需要在配置文件 ...

  4. java如何通过grpc连接etcd_grpc通过 etcd 实现服务发现与注册-源码分析

    介绍 下面介绍 jupiter-0.2.7 版本中 grpc 通过 etcd 实现服务发现与注册. 服务发现与注册的实现解析 服务注册 服务注册的流程图: etcd的服务注册代码模块在 jupiter ...

  5. Netty游戏服务器实战开发(6):Netty整合Zookeeper实现分布式服务发现与注册

    1:Zookeeper基础 安装zookeeper.当然,很多时候我们会在Windows上开发,所以,我们需要在本地搭建一个zookeeper环境.方便开发过程中的测试. 首先我们去Apache上下载 ...

  6. 分布式服务发现与注册中心 Consul 中文入门指南

    公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你玩转 Linux ! 基础概念 什么是注册中心 随着微服务理论发展的成熟,越来越多互联网公司采用微服务架构来支持业务发展.各个微服务之间 ...

  7. python服务发现与注册_(转)微服务架构中服务注册与发现

    https://blog.csdn.net/u011537073/article/details/69663858 想象一下,如果你在写代码调用一个有REST API或Thrift API的服务,你的 ...

  8. 这就是你日日夜夜想要的docker!!!---------docker+consul+ nginx集成分布式的服务发现与注册架构

    文章目录 一.Docker consul容器服务更新与发现理论 1.基本架构 2.基于nginx和consul构建高可用及自动发现的Docker服务架构 3.Docker consul自动发现服务架构 ...

  9. springcloud微服务简单实例(服务发现与注册)

    原理图: 一.架构 1.创建一个SPRINGCLOUD项目 2.添加依赖: <parent><groupId>org.springframework.boot</grou ...

最新文章

  1. python自动发送微信公众号_使用python一步一步搭建微信公众平台(四)----将小黄鸡引入微信自动回复...
  2. 3DSlicer5:开发者必晓ABC
  3. 非参数密度估计(直方图与核密度估计)
  4. 方法:求两个数之和 判断两数是否相等
  5. 交换机开发(四)—— ARP 基础知识解析
  6. 【转】关于CLR内存管理一些深层次的讨论[下篇]
  7. node mysql 增删改查_Nodejs操作MySQL - 增删改查
  8. 网络爬虫数据挖掘_我如何构建无服务器网络爬虫以大规模挖掘温哥华房地产数据...
  9. CGAffineTransformMakeRotation 实现旋转
  10. webrtc2sip项目说明
  11. 第五章 线性回归 学习笔记下
  12. python植物大战僵尸图片素材_Python 植物大战僵尸代码实现: 图片加载和显示切换...
  13. linux aria2安装路径,Aria2 Linux 完整安装及使用教程
  14. 几种常用的Web安全认证方式
  15. 移动应用开发课堂总结
  16. 修改win7的登录界面背景与关机背景
  17. 【数据库】SQL Server的使用教程
  18. Linux学习笔记:联想拯救者Y7000进BIOS
  19. 谈谈数据库中的日期、时间、日期时间、时间戳
  20. 信息学奥赛一本通:1312:【例3.4】昆虫繁殖

热门文章

  1. 网页HTML5制作flex布局骰子,CSS3的Flexbox骰子布局的实现及分析
  2. webpack 打包第三方库_Webpack 打包第三方代码库
  3. CVX学习笔记(转载
  4. 设计模式004:抽象工厂模式
  5. 20天掌握Pytorch文档链接
  6. nor flash和nand flash
  7. 最小环 floyd java_Floyd最小环
  8. 求出m~n的整数中1出现的次数
  9. [LeetCode] Z字型变换
  10. 无法执行该VI,必须使用LabVIEW完整版开发系统才可以解决该错误