Nacos注册中心简介

背景分析

在微服务中,首先需要面对的问题就是如何查找服务(软件即服务),其次,就是如何在不同的服务之间进行通信?如何更好更方便的管理应用中的每一个服务,如何建立各个服务之间联系的纽带,由此注册中心诞生(例如淘宝网卖家提供服务,买家调用服务)。
市面上常用注册中心有Zookeeper(雅虎Apache),Eureka(Netfix),Nacos(Alibaba),Consul(Google),那他们分别都有什么特点,我们如何进行选型呢?我们主要从社区活跃度,稳定性,功能,性能等方面进行考虑即可.本次微服务的学习,我们选择Nacos,它很好的支持了阿里的双11活动,不仅可以做注册中心,还可以作为配置中心,稳定性和性能都很好.

Nacos概述

Nacos(DynamicNaming and Configuration Service)是一个应用于服务注册与发现、配置管理的平台。它孵化于阿里巴巴,成长于十年双十一的洪峰考验,沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。其官网地址如下:

https://nacos.io/zh-cn/docs/quick-start.html

构建Nacos服务

下载与安装

第一步:Nacos下载,可在浏览器直接输入如下地址:

https://github.com/alibaba/nacos/releases

第二步:选择对应版本,直接下载,如图所示:

第三步:解压Nacos(最好不要解压到中文目录下),其目录结构如下:

初始化配置

第一步:找到/conf/nacos-mysql.sql文件里的sql脚本,然后登陆mysql,然后基于脚本文件中的描述创建数据库(名字nacos_config,编码方式utf8mb4),并执行脚本文件(也可以直接使用老师上课发的nacos-mysql.sql),脚本执行成功会创建一些表,如图所示:

说明:在执行此文件时,要求mysql的版本大于5.7版本(MariaDB最好10.5.11),否则会出现如下错误:

第二步:打开/conf/application.properties里打开默认配置,并基于你当前环境配置要连接的数据库,连接数据库时使用的用户名和密码(假如前面有"#"要将其去掉):

### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=root

服务启动与访问

第一步:启动Nacos服务。

Linux/Unix/Mac启动命令(standalone代表着单机模式运行,非集群模式):

./startup.sh -m standalone

Windows启动命令(standalone代表着单机模式运行,非集群模式):

startup.cmd -m standalone

说明:
1)执行执行令时要么配置环境变量,要么直接在nacos/bin目录下去执行.
2)nacos启动时需要本地环境变量中配置了JAVA_HOME(对应jdk的安装目录),

第二步:访问Nacos服务。

打开浏览器,输入http://localhost:8848/nacos地址,出现如下登陆页面:

其中,默认账号密码为nacos/nacos.

服务注册与调用入门(重点)

业务描述

创建两个项目Module分别为服务提供者和服务消费者,两者都要注册到NacosServer中(这个server本质上就是一个web服务,端口默认为8848),然后服务提供者可以为服务消费者提供远端调用服务(例如支付服务为服务提供方,订单服务为服务消费方),如图所示:

创建Maven父工程

创建maven module工程01-sca,此工程为我们后续项目模块的父工程,这个工程的作用就是来管理子模块中所需要的共性依赖,如图所示:

通过此工程管理其核心依赖,其pom文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.cy</groupId><artifactId>01-sca </artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging>    <properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring.cloud-version>Hoxton.SR8</spring.cloud-version><spring.cloud.alibaba-version>2.2.5.RELEASE</spring.cloud.alibaba-version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud-version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring.cloud.alibaba-version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>

其中的版本可参考如下网址(涉及到一个兼容性问题,不能随意指定其版本):

https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

说明:父工程资源初始化完成以后,将src目录删除,因为父工程只负责依赖管理.

生产者服务创建及注册

第一步:创建服务提供者继承parent工程(01-msa),module名为sca-nacos-provider(创建module工程时在父工程上右键创建module)。

第二步:添加项目依赖,关键代码如下:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
</dependencies>

第三步:创建并修改配置文件application.yml(或者application.properties),实现服务注册,关键代码如下:

server:port: 8081
spring:application:name: sca-providercloud:nacos:server-addr: localhost:8848

注意:服务名不要使用下划线(“_”),应使用横杠(“-”),这是规则。
第四步:创建启动类,并定义处理请求的控制层对象和方法,关键代码如下:

package com.cy;
@SpringBootApplication
public class ScaProviderApplication {public static void main(String[] args) {SpringApplication.run(ScaProviderApplication.class, args);}
@Value("${server.port}")
private String server;@RestControllerpublic class ProviderController {@GetMapping(value = "/provider/echo/{msg}")public String doEcho(@PathVariable String msg) {return server+"say:Hello Nacos Discovery " + msg;}}
}

第五步:启动启动类,然后刷先nacos服务,检测是否服务注册成功,如图所示:

第六步:打开浏览器,输入http://localhost:8081/provider/echo/msa,然后进行访问。

消费者服务发现及调用

第一步:创建服务消费者继承parent工程,module名为sca-nacos-consumer。

第二步:添加项目依赖,关键代码如下:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
</dependencies>

第三步:修改配置文件application.yml,关键代码如下:

server:port: 8090
spring:application:name: sca-consumercloud:nacos:discovery:server-addr: localhost:8848 #从哪里去查找服务

第四步:创建启动类并实现服务消费,关键代码如下:

package com.cy;
@SpringBootApplication
public class ScaConsumerApplication {public static void main(String[] args) {SpringApplication.run(ScaConsumerApplication.class,args);}@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}@RestControllerpublic class ConsumerController{@Value("${spring.application.name}")private String appName;@Autowiredprivate RestTemplate restTemplate;@GetMapping("/consumer/doRestEcho1")public String doRestEcho01(){String url = "http://localhost:8081/provider/echo/"+appName;System.out.println("request url:"+url);return restTemplate.getForObject(url, String.class);}}
}

第五步:启动消费者服务,并在浏览器输入http://localhost:8090/consumer/doRestEcho1地址进行访问,假如访问成功会出现,如图所示效果:

小节面试分析

  • 为什么要将服务注册到nacos?(为了更好的查找这些服务)
  • 在Nacos中服务提供者是如何向Nacos注册中心(Registry)续约的?(5秒心跳)
  • 对于Nacos服务来讲它是如何判定服务实例的状态?(检测心跳包,15,30)
  • 服务启动时如何找到服务启动注册配置类?(NacosNamingService)
  • 服务消费方是如何调用服务提供方的服务的?(RestTemplate)

服务负载均衡设计及实现(重点)

入门案例

一个服务实例可以处理请求是有限的,假如服务实例的并发访问比较大,我们会启动多个服务实例,让这些服务实例采用一定策略均衡(轮询,权重,随机,hash等)的处理并发请求,在Nacos中服务的负载均衡(Nacos客户端负载均衡)是如何应用的?

第一步:修改ConsumerController类,注入LoadBalancerClient对象,
并添加doRestLoadBalancerClientEcho方法,然后进行服务访问.

@Autowiredprivate LoadBalancerClient loadBalancerClient;   @GetMapping("/consumer/doRestEcho02")public String doRestEcho02(){ServiceInstance serviceInstance = loadBalancerClient.choose("sca-provider");String url = String.format("http://%s:%s/provider/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);System.out.println("request url:"+url);return restTemplate.getForObject(url, String.class);}}

第二步:打开Idea服务启动配置,如图所示:

第三步:修改并发运行选项(假如没有找到这个选项我们需要通过搜索引擎基于组合查询的方法,去找到对应的解决方案,例如搜索 idea allow parallel run),如图所示:

第四步:修改sca-provider的配置文件端口,分别以8081,8082端口方式进行启动。

server:port: 8081
spring:application:name: sca-providercloud:nacos:server-addr: localhost:8848

启动成功以后,访问nacos的服务列表,检测服务是否成功注册,如图所示:

第四步:启动sca-consumer项目模块,打开浏览器,输入如下网址进行反复服务访问:

http://localhost:8090/consumer/doRestEcho02

然后会发现sca-provider的两个服务都可以处理sca-consumer的请求。


这里多个实例并发提供服务的方式为负载均衡,这里的负载均衡实现默认是因为Nacos集成了Ribbon来实现的,Ribbon配合RestTemplate,可以非常容易的实现服务之间的访问。Ribbon是Spring Cloud核心组件之一,它提供的最重要的功能就是客户端的负载均衡(客户端可以采用一定算法,例如轮询访问,访问服务端实例信息),这个功能可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡方式的服务调用。

@LoadBalanced

当使用RestTemplate进行远程服务调用时,假如需要负载均衡,可以在RestTemplate对象构建时,使用@LoadBalanced对构建RestTemplate的方法进行修饰,例如在ScaConsumerApplication中构建RestTemplate对象:

@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate(){return new RestTemplate();
}

在需要RestTemplate实现负载均衡调用的地方进行依赖注入.例如在ConsumerController类中添加loadBalancedRestTemplate属性

@Autowired
private RestTemplate loadBalancedRestTemplate;

接下来,可以在对应的服务端调用方的方法内,基于RestTemplate借助服务名进行服务调用, 例如:

@GetMapping("/consumer/doRestEcho3")
public String doRestEcho03(){String url=String.format("http://%s/provider/echo/%s",
"sca-provider",appName);//向服务提供方发起http请求,获取响应数据return loadBalancedRestTemplate.getForObject(url,//要请求的服务的地址String.class);//String.class为请求服务的响应结果类型
}

RestTemplate在发送请求的时候会被LoadBalancerInterceptor拦截,它的作用就是用于RestTemplate的负载均衡,LoadBalancerInterceptor将负载均衡的核心逻辑交给了loadBalancer,核心代码如下所示(了解):

public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {final URI originalUri = request.getURI();String serviceName = originalUri.getHost();return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
}

@LoadBalanced注解是属于Spring,而不是Ribbon的,Spring在初始化容器的时候,如果检测到Bean被@LoadBalanced注解,Spring会为其设置LoadBalancerInterceptor的拦截器。

Ribbon负载均衡策略(了解)

基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,对于SpringCloud Alibaba解决方案中又提供了NacosRule策略,默认的负载均衡策略是轮训策略。如图所示:

当系统提供的负载均衡策略不能满足我们需求时,我们还可以基于IRule接口自己定义策略.

小节面试分析

  • @Bean注解的作用?(一般用于配置类内部,描述相关方法,用于告诉spring此方法的返回值要交给spring管理,bean的名字默认为方法名,假如需要指定名字可以@Bean(“bean的名字”),最多的应用场景是整合第三方的资源-对象)
  • @Autowired注解的作用?(此注解用于描述属性,构造方法,set方法等,用于告诉spring框架,按找一定的规则为属性进行DI操作,默认按属性,方法参数类型查找对应的对象,假如只找到一个,则直接注入,类型多个时还会按照属性名或方法参数名进行值的注入,假如名字也不同,就出报错.)
  • Nacos中的负责均衡底层是如何实现的?(通过Ribbon实现,Ribbon中定义了一些负载均衡算法,然后基于这些算法从服务实例中获取一个实例为消费方法提供服务)
  • Ribbon 是什么?(Netflix公司提供的负载均衡客户端,一般应用于服务的消费方法)
  • Ribbon 可以解决什么问题? (基于负载均衡策略进行服务调用, 所有策略都会实现IRule接口)
  • Ribbon 内置的负载策略都有哪些?(8种,可以通过查看IRule接口的实现类进行分析)
  • @LoadBalanced的作用是什么?(描述RestTemplate对象,用于告诉Spring框架,在使用RestTempalte进行服务调用时,这个调用过程会被一个拦截器进行拦截,然后在拦截器内部,启动负载均衡策略。)
  • 我们可以自己定义负载均衡策略吗?(可以,基于IRule接口进行策略定义,也可以参考NacosRule进行实现)

基于Feign的远程服务调用(重点)

背景分析

服务消费方基于rest的请求服务提供方的服务时,一种直接的方式就是自己拼接url,拼接参数然后实现服务调用,但每次服务调用都需要这样拼接,打码量复杂且不易维护,此时Feign诞生。

Feign是什么

Feign 是一种声明式Web服务客户端,底层封装了对Rest技术的应用,通过Feign可以简化服务消费方对远程服务提供方法的调用实现。如图所示:

Feign 最早是由 Netflix 公司进行维护的,后来 Netflix 不再对其进行维护,最终 Feign 由社区进行维护,更名为 OpenFeign。

Feign应用实践(掌握)

第一步:在服务消费方,添加项目依赖(SpringCloud团队基于OpenFeign研发了starter),代码如下:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

第二步:在启动类上添加@EnableFeignClients注解,代码如下:

@EnableFeignClients
@SpringBootApplication
public class ScaConsumerApplication {…}

第三步:定义Http请求API,基于此API借助OpenFeign访问远端服务,代码如下:

@FeignClient(name="sca-provider")//sca-provider为服务提供者名称
interface RemoteProviderService{@GetMapping("/provider/echo/{string}")//前提是远端需要有这个服务public String echoMessage(@PathVariable("string") String string);
}

其中,@FeignClient描述的接口底层会为其创建实现类。

第四步:创建FeignConsumerController中并添加feign访问,代码如下:


@RestController
@RequestMapping("/consumer/ ")
public class FeignConsumerController {@Autowiredprivate RemoteProviderService remoteProviderService;/**基于feign方式的服务调用*/@GetMapping("/echo/{msg}")public String doFeignEcho(@PathVariable  String msg){//基于feign方式进行远端服务调用(前提是服务必须存在)return remoteProviderService.echoMessage(msg);}
}

第五步:启动消费者服务,在浏览器中直接通过feign客户端进行访问,如图所示(反复刷新检测其响应结果):

Feign配置进阶实践

一个服务提供方通常会提供很多资源服务,服务消费方基于同一个服务提供方写了很多服务调用接口,此时假如没有指定contextId,服务
启动就会失败,例如假如在服务消费方再添加一个如下接口,消费方启动时就会启动失败,例如:

 @FeignClient(name="sca-provider")public interface RemoteOtherService {@GetMapping("/doSomeThing")public String doSomeThing();
}

其启动异常:

The bean 'optimization-user.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.

此时我们需要为远程调用服务接口指定一个contextId,作为远程调用服务的唯一标识即可,例如:

@FeignClient(name="sca-provider",contextId="remoteProviderService")//sca-provider为服务提供者名称
interface RemoteProviderService{@GetMapping("/provider/echo/{string}")//前提是远端需要有这个服务public String echoMessage(@PathVariable("string") String string);
}

还有,当我们在进行远程服务调用时,假如调用的服务突然不可用了或者调用过程超时了,怎么办呢?一般服务消费端会给出具体的容错方案,例如:
第一步:定义FallbackFactory接口的实现,代码如下:

package com.cy.service.factory;
/*** 基于此对象处理RemoteProviderService接口调用时出现的服务中断,超时等问题*/
@Component
public class ProviderFallbackFactoryimplements FallbackFactory<RemoteProviderService> {/*** 此方法会在RemoteProviderService接口服务调用时,出现了异常后执行.* @param throwable 用于接收异常*/@Overridepublic RemoteProviderService create(Throwable throwable) {return (msg)->{return "服务维护中,稍等片刻再访问";};}
}

第二步:在Feign访问接口中应用FallbackFactory对象,例如:

@FeignClient(name = "sca-provider",contextId = "remoteProviderService",fallbackFactory = ProviderFallbackFactory.class)//sca-provider为nacos中的服务名
public interface RemoteProviderService {@GetMapping("/provider/echo/{msg}")public String echoMsg(@PathVariable String msg);
}

第三步:在配置文件application.yml中添加如下配置,启动feign方式调用时的服务中断处理机制.

feign:  hystrix:enabled: true #默认值为false

第四步:在服务提供方对应的方法中添加Thread.sleep(500000)模拟耗时操作,然后启动服务进行访问测试.

Feign 调用过程分析(了解)

Feign应用过程分析(底层逻辑先了解):
1)通过 @EnableFeignCleints 注解告诉springcloud,启动 Feign Starter 组件。
2) Feign Starter 在项目启动过程中注册全局配置,扫描包下所由@FeignClient注解描述的接口,然后由系统底层创建接口实现类(JDK代理类),并构建类的对象,然后交给spring管理(注册 IOC 容器)。
3) 接口被调用时被动态代理类逻辑拦截,将 @FeignClient 请求信息通过编码器生成 Request对象,基于此对象进行远程过程调用。
4) 请求对象经Ribbon进行负载均衡,挑选出一个健康的 Server 实例(instance)。
5) 通过 Client 携带 Request 调用远端服务返回请求响应。
6) 通过解码器生成 Response 返回客户端,将信息流解析成为接口返回数据。

小节面试分析

  • 为什么使用feign?(基于Feign可以更加友好的实现服务调用,简化服务消费方对服务提供方方法的调用)。
  • @FeignClient注解的作用是什么?(告诉Feign Starter,在项目启动时,为此注解描述的接口创建实现类-代理类)
  • Feign方式的调用,底层负载均衡是如何实现的?(Ribbon)
  • @EnableFeignCleints 注解的作用是什么?(描述配置类,例如启动类)

总结(Summary)

重难点分析

  • 何为注册中心?(用于记录服务信息的一个web服务,例如淘宝平台,滴滴平台,美团外卖平台,……)
  • 注册中心的核心对象?(服务提供方,服务消费方,注册中心-Registry)
  • 市面上常用注册中心?(Google-Consul,Alibaba-Nacos,…)
  • 微服务架构下项目的构建过程?(聚合工程)
  • Nacos安装、启动、服务的注册、发现机制以及实现过程?
  • Feign的基本应用以及底层底层调用原理?

FAQ分析

  • Nacos是什么,提供了什么特性(服务的注册、发现、配置)?
  • 你为什么会选择Nacos?(活跃度、稳定、性能、学习成本)
  • Nacos的官网?(nacos.io)
  • Nacos在github的源码?(github.com/alibaba/nacos)
  • Nacos在windows环境下安装?(解压即可使用)
  • Nacos在windows中的的初步配置?(application.properties访问数据库的数据源)
  • Nacos服务注册的基本过程?(服务启动时发送web请求)
  • Nacos服务消费的基本过程?(服务启动时获取服务实例,然后调用服务)
  • Nacos服务负载均衡逻辑及设计实现?(Ribbon)
  • 注册中心的核心数据是什么?(服务的名字和它对应的网络地址)
  • 注册中心中心核心数据的存取为什么会采用读写锁?(底层安全和性能)
  • Nacos健康检查的方式?(基于心跳包机制进行实现)
  • Nacos是如何保证高可用的?(重试,本地缓存、集群)
  • Feign是什么,它的应用是怎样的,feign应用过程中的代理对象是如何创建的(JDK)?
  • Feign方式的调用过程,其负载均衡是如何实现?(Ribbon)

Bug分析

  • 404
  • 400
  • 405
  • 415
  • 500
  • ………

Java学习四阶段-07 服务注册中心Nacos相关推荐

  1. 服务注册中心Nacos

    文章目录 一.服务注册中心Nacos最佳实践 1.Nacos注册中心简介 背景分析 Nacos概述 构建Nacos服务 初始化配置 服务启动与访问 2.服务注册与调用入门(重点) 业务描述 生产者服务 ...

  2. 微服务注册中心 Nacos 实现原理详解!

    Nacos 架构 Provider APP:服务提供者 Consumer APP:服务消费者 Name Server:通过VIP(Virtual IP)或DNS的方式实现Nacos高可用集群的服务路由 ...

  3. Java学习四阶段-09 Sentinel限流熔断

    Sentinel简介 背景分析 在我们日常生活中,经常会在淘宝.天猫.京东.拼多多等平台上参与商品的秒杀.抢购以及一些优惠活动,也会在节假日使用12306 手机APP抢火车票.高铁票,甚至有时候还要帮 ...

  4. Java学习四阶段-JUC并发包

    文章目录 JUC包中的锁应用 Lock接口及ReentrantLock对象分析及应用? Condition接口对象分析与应用? ReadWriteLock接口及实现类分析与应用? StampedLoc ...

  5. 散装版学习笔记 - Dubbo配合Multicast作为服务注册中心示例

    一.背景 上一篇记录了下SpringCloud使用Eureka作为服务注册中心的简单示例,文末并未提及使用过程中的感受以及总结,在此先做个小结,主要有以下两点: 整体环境配置简单,只需考虑依赖和app ...

  6. java 服务注册中心_服务治理的含义和java最流行的微服务框架服务治理注册中心的搭建...

    原标题:服务治理的含义和java最流行的微服务框架服务治理注册中心的搭建 Spring Cloud Eureka基于Netflix Eureka做了二次封装,是Spring Cloud Netflix ...

  7. java服务注册中心有哪些_Spring Cloud服务注册中心简述

    概念 当一个大型系统拥有很多服务时,往往需要一个服务注册中心来管理这些服务,它可以提供如下功能: 登记每个服务提供的功能 检测每个服务是否可用,不可用的服务剔除 服务间互相调用时,通过服务注册中心很容 ...

  8. java版b2b2c社交电商spring cloud分布式微服务(十)高可用的服务注册中心

    电子商务社交平台源码请加企鹅求求:一零三八七七四六二六.文章 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka) 介绍了服务注册与发现,其中服务注册中心Eure ...

  9. java技术--服务注册中心

    1.在微服务架构中,注册中心是核心的基础服务之一 2.服务治理的实现主要依靠的就是注册中心,用来进行服务的发现与注册 3.什么是注册中心 (1)注册中心可以说是微服务架构中的"通讯录&quo ...

最新文章

  1. 如何得到iterator的当前元素_链表进化!双向链表+迭代器(Iterator)!
  2. 数据库相关子查询实例
  3. 由Android 65K方法数限制引发的思考
  4. 2019-11-13 惯性环节怎么写成m语言
  5. anaconda 更改路径_Anaconda更改Jupyter 默认启动路径
  6. 联手友盟+打造云上数据增长“样板间”, 好兔视频成功逆势突围
  7. tcp欢动窗口机制_TCP协议中的窗口机制------滑动窗口详解
  8. python数据可视化实现步骤,Python 代码轻松实现数据可视化的5 种使用方法
  9. cvpr2020 人脸检测与识别_Python人脸检测识别实例教程
  10. Java集合---ConcurrentHashMap原理分析
  11. 作业(数组)---运行环境winTC(二)
  12. ECCV2022 | 多任务SOTA模型!分割/深度/边界/显著图四项任务
  13. 【GIT】error: failed to push some refs to 'https://github.com/username/python.git'
  14. Python之修改图片像素值
  15. OpenMesh-网格光顺的算法
  16. mac连接蓝牙耳机只有一个有声音
  17. IntelliJ IDEA破解版 2017.3.4 Ultimate下载安装和JetbrainsCrack-2.7.jar激活教程
  18. JS/Jquery 中移除子元素的问题
  19. 来拿,腾讯数据开发整理的用户留存分析(超详细)
  20. Outlook使用RTF格式发信出现Winmail.dat附件事宜

热门文章

  1. 几款名壶的来历(图片)
  2. 杯中窥人,王者创业——致敬韩寒
  3. 短链接生成-短网址生成-短网址生成接口-短网址URL生成-短链接-短链接URL生成接口
  4. C语言的与短路和或断路
  5. e舞成名3月新歌脚谱更新
  6. 如何使用 CSS 自定义无序列表样式
  7. 全栈工程师知识点汇总——html5(上)
  8. redhat 安装redash
  9. 信创国产化,高速数据传输系统-UTS
  10. 分析报告不懂怎么布局最佳?两套通用模板适合各种报告类型