怎么看调用的接口_SpringCloud服务间调用

本篇简介

在上一篇我们介绍了SpringCloud中的注册中心组件Eureka。Eureka的作用是做服务注册与发现的,目的是让不同的服务与服务之间都可以通过注册中心进行间接关联,并且可以通过注册中心有效的管理不同服务与服务的运行状态。但在微服务的架构中,服务与服务只知道对方的服务地址是没有用的,它们的本质还是需要彼此进行通信的,这也是微服务最核心的功能之一。


既然提到了服务与服务之间的通信,那我们自然而然会想到大名鼎鼎的HttpClient。因为在其它的项目架构中我们基本都可以通过它来进行不同服务与服务之间的调用。在SpringCloud中我们依然可以使用HttpClient进行服务与服务调用,只不过如果采用HttpClient调用的话,会有一些弊端。例如: 如果同一个服务有多个负载的话,采用HttpClient调用时,没有办法处理负载均衡的问题。还有另一个问题就是HttpClient只是提供了核心调用的方法并没有对调用进行封装,所以在使用上不太方便,需要自己对HttpClient进行简单的封装。


调用方式

在SpringCloud中为了解决服务与服务调用的问题,于是提供了两种方式来进行调用。也就是RestTemplate和Feign。虽然从名字上看这两种调用的方式不同,但在底层还是和HttpClient一样,采用http的方式进行调用的。只不过是对HttpClient进行的封装。下面我们来详细的介绍一下这两种方式的区别,我们首先看一下RestTemplate的方式。


RestTemplate方式调用

  • RestTemplate

为了方便掩饰我们服务间的调用,所以我们需要创建三个项目。它们分别为eureka(注册中心)、server(服务提供方)、client(服务调用方)。因为上一篇中我们已经介绍了eureka的相关内容。所以在这一篇中我们将不在做过多的介绍了。下面我们看一下server端的配置。因为实际上Server端和Client端是相互的。不一定client端一定要调用server端。server端一样可以调用client端。但对于eureka来说,它们都是client端。因为上一篇中我们已经介绍了eureka是分为server端和client端的,并且已经介绍client端相关内容。所以我们下面我们直接看一下server端的配置内容:

eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
spring:
application:
name: jilinwula-springcloud-feign-server
server:
port: 8082

为了掩饰我们服务间的调用,所以我们需要创建一个Controller,并编写一个简单的接口来供client调用。下面为server的源码。

package com.jilinwula.feign.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/server")
public class Controller {

@GetMapping("/get")
public Object get() {
Map<String, String> map = new HashMap<String, String>();
map.put("code", "0");
map.put("msg", "success");
map.put("data", "吉林乌拉");
return map;
}
}

下面我们访问一下这个接口看看,是否能正确返回数据。(备注:注意别忘记了在启动类上添加@EnableEurekaClient注解。)下面我们还是使用.http文件的方式发起接口请求。

GET http://127.0.0.1:8082/server/get

返回结果:

GET http://127.0.0.1:8082/server/get

HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 15 Mar 2019 08:20:33 GMT

{
"msg": "success",
"code": "0",
"data": "吉林乌拉"
}

Response code: 200; Time: 65ms; Content length: 42 bytes

我们看已经成功的返回了接口的数据了。下面我们看一下eureka。看看是否成功的检测到了server端的服务。下面为eureka管理界面地址:

http://127.0.0.1:8761

  eaf2cfac1716b142b053ae7153daa4ee.png

我们看eureka已经成功的检测到了server端注册成功了。下面我们看一下client端的代码,我们还是向server端一样,创建一个Controller,并编写一个接口。下面为具体配置及代码。

application.yml:

eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
spring:
application:
name: jilinwula-springcloud-feign-client
server:
port: 8081

  Controller:

package com.jilinwula.feign.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/client")
public class Controller {

@GetMapping("/get")
public Object get() {
Map<String, String> map = new HashMap<String, String>();
map.put("code", "0");
map.put("msg", "success");
map.put("data", "吉林乌拉");
return map;
}
}

下面为访问的接口地址:

GET http://127.0.0.1:8081/client/get

返回结果:

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 15 Mar 2019 08:56:42 GMT

{
"msg": "success",
"code": "0",
"data": "吉林乌拉"
}

Response code: 200; Time: 273ms; Content length: 42 bytes

现在我们在访问一下Eureka地址看一下Client服务注册的是否成功。

http://127.0.0.1:8761

  675b92f2f072be4b3a33a5d5f30eb0ba.png

RestTemplate实例化

我们发现server和client端都已经成功的在注册中心注册成功了。这也就是我们接下来要介绍的服务间调用的前提条件。在开发Spring项目时我们知道如果我们想要使有哪个类或者哪个对象,那就需要在xml中或者用注解的方式实例化对象。所以既然我们打算使用RestTemplate类进行调用,那我们必须要先实例化RestTemplate类。下面我们就看一下怎么在实例化RestTemplate类。因为不论采用的是RestTemplate方式调用还是采用Feign方式,均是在服务的client端进行开发的,在服务的server是无需做任何更改的。所以下面我们看一下client端的改动。下面为项目源码:

package com.jilinwula.feign;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class JilinwulaSpringcloudFeignClientApplication {

public static void main(String[] args) {
SpringApplication.run(JilinwulaSpringcloudFeignClientApplication.class, args);
}

@Bean
public RestTemplate initRestTemplate() {
return new RestTemplate();
}

}

RestTemplate调用方式一

为了掩饰方便我们直接在启动类上添加了一个@Bean注解。然后手动实例化了一个对象,并且要特别注意,在使用RestTemplate时,必须要先实例化,否则会抛出空指针异常。下面我们演示一下怎么使用RestTemplate来调用server端的接口。下面为Controller中的代码的改动。

package com.jilinwula.feign.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/client")
public class Controller {

@Autowired
private RestTemplate template;

@GetMapping("/get")
public Object get() {
String result = template.getForObject("http://127.0.0.1:8082/server/get", String.class);
return result;
}
}

上面的代码比较简单,我们就不详细的介绍了,主要是RestTemplate中提供了getForObject方法(实际上RestTemplate提供了很多种调用的方法,主要分为Get或者Post),可以指定要调用接口的地址,指定返回的值的类型。然后就会直接返回要调用接口的结果。下面我们测试一下,还是调用client接口,看看能否正确的返回server端的数据。

http://127.0.0.1:8081/client/get

返回结果:

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 50
Date: Fri, 15 Mar 2019 09:42:02 GMT

{"msg":"success","code":"0","data":"吉林乌拉"}

Response code: 200; Time: 362ms; Content length: 42 bytes

RestTemplate调用方式二

我们看结果,已经成功的返回的server端的数据了,虽然返回的数据没有格式化,但返回的结果数据确实是server端的数据。这也就是RestTemplate的简单使用。但上述的代码是有弊端的,因为我们直接将调用的server端的接口地址直接写死了,这样当服务接口变更时,是需要更改客户端代码的,这显示是不合理的。那怎么办呢?这时就知道注册中心的好处了。因为注册中心知道所有服务的地址,这样我们通过注册中心就可以知道server端的接口地址,这样就避免了server端服务更改时,要同步更改client代码了。下面我们在优化一下代码,看看怎么通过注册中心来获取server端的地址。

package com.jilinwula.feign.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/client")
public class Controller {

@Autowired
private RestTemplate template;

@Autowired
private LoadBalancerClient loadBalancerClient;

@GetMapping("/get")
public Object get() {
ServiceInstance serviceInstance = loadBalancerClient.choose("jilinwula-springcloud-feign-server");
String url = String.format("http://%s:%s/server/get", serviceInstance.getHost(), serviceInstance.getPort());
String result = template.getForObject(url, String.class);
return result;
}
}

在SpringClourd中提供了LoadBalancerClient接口。通过这个接口我们可以通过用户中心的Application的名字来获取该服务的地址和端口。也就是下图中红色标红的名字(注意名字大小写)。

  df03844e3b62df15d70f88fefbd6c2ad.png

通过这些我们就可以获取到完整的服务接口地址了,这样就可以直接通过RestTemplate进行接口调用了。下面我们在看一下调用的结果。接口地址:

GET http://127.0.0.1:8081/client/get

返回结果:

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 50
Date: Sat, 16 Mar 2019 09:08:32 GMT

{"msg":"success","code":"0","data":"吉林乌拉"}

Response code: 200; Time: 53ms; Content length: 42 bytes

RestTemplate调用方式三

这样我们就解决了第一次服务接口地址写死的问题了。但上述的接口还有一个弊端就是我们每次调用服务时都要先通过Application的名字来获取ServiceInstance对象,然后才可以发起接口调用。实际上在SpringCloud中为我们提供了@LoadBalanced注解,只要将该注解添加到RestTemplate中的获取的地方就可以了。下面为具体修改:

启动类:

package com.jilinwula.feign;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class JilinwulaSpringcloudFeignClientApplication {

public static void main(String[] args) {
SpringApplication.run(JilinwulaSpringcloudFeignClientApplication.class, args);
}

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

}

我们在RestTemplate实例化的地方添加了@LoadBalanced注解,这样在我们使用RestTemplate时就该注解就会自动将调用接口的地址替换成真正的服务地址。下面我们看一下Controller中的改动:

package com.jilinwula.feign.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/client")
public class Controller {

@Autowired
private RestTemplate template;

@GetMapping("/get")
public Object get() {
String url = String.format("http://%s/server/get", "jilinwula-springcloud-feign-server");
String result = template.getForObject(url, String.class);
return result;
}
}

代码和第一次的代码基本一样,唯一的区别就是获取服务地址和端口的地方替换成了注册中心中的Application的名字,并且我们的RestTemplate在使用上和第一次没有任何区别,只是在url中不同。下面我们看一下返回的结果。

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 50
Date: Sat, 16 Mar 2019 09:55:46 GMT

{"msg":"success","code":"0","data":"吉林乌拉"}

Response code: 200; Time: 635ms; Content length: 42 bytes

默认负载均衡策略

上述内容就是使用RestTemplate来进行服务间调用的方式。并且采用这样的方式可以很方便的解决负载均衡的问题。因为@LoadBalanced注解会自动采用默信的负载策略。下面我们看验证一下SpringCloud默认的负载策略是什么。为了掩饰负载策略,所以我们在新增一个server服务,并且为了掩饰这两个server返回结果的不同,我们故意让接口返回的数据不一致,来方便我们测试。下面为新增的server服务端的配置信息及controller源码。

application.yml:

eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
spring:
application:
name: jilinwula-springcloud-feign-server
server:
port: 8083

  Controller:

package com.jilinwula.feign.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/server")
public class Controller {

@GetMapping("/get")
public Object get() {
Map<String, String> map = new HashMap<String, String>();
map.put("code", "0");
map.put("msg", "success");
map.put("data", "jilinwula");
return map;
}
}

调用以下接口:

GET http://127.0.0.1:8083/server/get

返回结果:

GET http://127.0.0.1:8083/server/get

HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 16 Mar 2019 10:49:07 GMT

{
"msg": "success",
"code": "0",
"data": "jilinwula"
}

Response code: 200; Time: 100ms; Content length: 47 bytes

现在我们访问一下注册中心看一下现在注册中心的变化。注册中心地址:

http://127.0.0.1:8761

  ce75e08c98d7530faad1dbd548a17456.png

我们看上图注册中心已经显示Application名字为JILINWULA-SPRINGCLOUD-FEIGN-SERVER的有两个服务已经注册成功了。下面我们直接调用client中的接口,看一下client默认会返回哪个server端的信息。client接口地址:

GET http://127.0.0.1:8081/client/get

返回结果:

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 47
Date: Sat, 16 Mar 2019 10:58:39 GMT

{"msg":"success","code":"0","data":"jilinwula"}

Response code: 200; Time: 24ms; Content length: 47 bytes

看上面返回的结果是server2的接口数据。我们在请求一下接口在看一下返回的结果:

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 50
Date: Sat, 16 Mar 2019 11:01:01 GMT

{"msg":"success","code":"0","data":"吉林乌拉"}

Response code: 200; Time: 15ms; Content length: 42 bytes

更改默认负载均衡策略一

我们看这回返回的接口数据就是第一个server端的信息了。并且我们可以频繁的调用client中的接口,并观察发现它们会交替返回的。所以我们基本可以确定SpringCloud默认的负载策略为轮询方式。也就是会依次调用。在SpringCloud中提供了很多种负载策略。比较常见的为:随机、轮询、哈希、权重等。下面我们介绍一下怎么修改默认的负载策略。SpringCloud底层采用的是Ribbon来实现的负载均衡。Ribbon是一个负载均衡器,Ribbon的核心组件为IRule,它也就是所有负载策略的父类。下面为IRule接口的源码:

package com.netflix.loadbalancer;

public interface IRule {
Server choose(Object var1);

void setLoadBalancer(ILoadBalancer var1);

ILoadBalancer getLoadBalancer();
}

该类只提供了3个方法,它们的作用分别是选择一个服务名字、设置ILoadBalancer和返回ILoadBalancer。下面我们看一下IRule接口的常见策略子类。常见的有RandomRule、RoundRobinRule、WeightedResponseTimeRule等。分别对应着随机、轮询、和权重。下面我们看一下怎么更改默认的策略方式。更改默认策略也是在client端中操作的,所以我们看一下client端的代码更改:

package com.jilinwula.feign;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class JilinwulaSpringcloudFeignClientApplication {

public static void main(String[] args) {
SpringApplication.run(JilinwulaSpringcloudFeignClientApplication.class, args);
}

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

@Bean
public IRule initIRule() {
return new RandomRule();
}

}

我们在启动类上新实例化了一个IRule对象,并且指定该对象实例化的子类为RandomRule,也就是随机的方式。所以当我们Client端启动服务调用服务时,就会采用随机的方式进行调用,因为我们已经将IRule对象默认的实例化方式更改了。下面我们测试一下,继续访问Client端接口:

GET http://127.0.0.1:8081/client/get

返回结果:

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 50
Date: Sat, 16 Mar 2019 11:36:01 GMT

{"msg":"success","code":"0","data":"吉林乌拉"}

Response code: 200; Time: 15ms; Content length: 42 bytes

更改默认负载均衡策略二

在这里我们就不依依演示了,但如果我们多次调用接口就会发现,Client接口返回的结果不在是轮询的方式了,而是变成了随机了,这就说明我们已经成功的将SpringCloud默认的负载策略更改了。下面我们换一种方式来更改默认的负载策略。这种方式和上面的有所不同,而是在配置文件中配置的,下面为具体的配置。(备注:为了不影响测试效果,我们需要将刚刚在启动类中的实例化的IRule注释掉)

eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
spring:
application:
name: jilinwula-springcloud-feign-client
server:
port: 8081
jilinwula-springcloud-feign-server:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

我们在配置文件中指定了注册中心中的server端的Application名字,然后指定了默认的负载策略类。下面我们测试一下。访问以下接口:

GET http://127.0.0.1:8081/client/get

返回结果:

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 50
Date: Sat, 16 Mar 2019 11:54:42 GMT

{"msg":"success","code":"0","data":"吉林乌拉"}

Response code: 200; Time: 13ms; Content length: 42 bytes

Feign方式调用

我们在实际的开发中,可以使用上述两种方式来更改SpringCloud中默认的负载策略。下面我们看一下SpringCloud中另一种服务间调用方式也就是Feign方式。使用Feign方式和RestTemplate不同,我们需要先添加Feign的依赖,具体依赖如下(备注:该依赖同样是在client端添加的):

pom.xml:

<dependency>
  <groupId>org.springframework.cloudgroupId>
  <artifactId>spring-cloud-starter-openfeignartifactId>
  <version>2.1.1.RELEASEversion>
dependency>

其次我们还需要在启动类中添加@EnableFeignClients注解。具体代码如下:

package com.jilinwula.feign;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class JilinwulaSpringcloudFeignClientApplication {

public static void main(String[] args) {
SpringApplication.run(JilinwulaSpringcloudFeignClientApplication.class, args);
}

}

接下来我们需要在Client端创建一个新的接口并定义Client端需要调用的服务方法。具体代码如下:

package com.jilinwula.feign.server;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "jilinwula-springcloud-feign-server")
public interface ServerApi {

@GetMapping("/server/get")
String get();
}

上述接口基本上和server端的Controller一致,唯一的不同就是我们指定了@FeignClient注解,该注解的需要指定一个名字,也就是注册中心中Applicaiton的名字,也就是要调用的服务名字。下面我们看一下Controller中的代码更改:

package com.jilinwula.feign.controller;

import com.jilinwula.feign.server.ServerApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/client")
public class Controller {

@Autowired
private ServerApi serverApi;

@GetMapping("/get")
public Object get() {
String result = serverApi.get();
return result;
}
}

我们在Controller中直接使用了我们自定义的接口,并直接调用我们接口中定义的方法,下面我们调用一下Client接口看看这样的方式是否可以调用成功。接口地址:

GET http://127.0.0.1:8081/client/get

返回结果:

GET http://127.0.0.1:8081/client/get

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 50
Date: Sat, 16 Mar 2019 12:54:50 GMT

{"msg":"success","code":"0","data":"吉林乌拉"}

Response code: 200; Time: 14ms; Content length: 42 bytes

我们看这样的方式也是可以成功的调用server端的接口的,只不过这样的方式可能会让觉的不太方便,因为这样的方式是需要Client端定义和Server端一样的接口的。


上述内容就是本篇的全部内容,在实际的项目开发中,这两种方式均可实现服务与服务间的调用,并且这两种方式都有彼此的弊端,所以并没有特别推荐的方式。在下一篇中,我们将介绍配置中心相关内容,谢谢。


项目源码

https://github.com/jilinwula/jilinwula-springcloud-feign


原文链接

http://jilinwula.com/article/...

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

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

相关文章

bimmercode刷隐藏教程_PS教程:快速提取人物像素,制作人物海报主体,简单易学...

这一篇主要是教大家快速提取人物像素&#xff0c;制作人物海报主体。主要是用快速复制移动快捷键(alt方向键)、单列框选工具、变形工具进行操作&#xff0c;简单快速。人物素材通过抠图得到&#xff0c;抠图方法用的是快速选择工具选择并遮住&#xff0c;这里就不说具体了&…

cass生成曲线要素文件_《CASS道路断面法施工技术》

技术分享&#xff0c;研究很久&#xff0c;分享一套CASS处理道路断面的施工方法技术&#xff0c;不懂的欢迎留言。CASS应用于道路类工程计算/ 1 /绘制道路中线道路中线一般由直线、圆曲线、缓和曲线段组成的复合线。CASS软件我们使用菜单中“公路曲线设计”生成。1、录入要素文…

dnf机械机器人补丁_干货 | 详解工业机器人控制系统架构

机械臂和移动机器人两种工业机器人的特点你知道吗&#xff1f;下面我们对比一下二者的控制系统方案。以上分类是根据应用对象&#xff0c;此外&#xff0c;市面上更多的是通用型运动控制器&#xff0c;即控制非标设备的。1 控制器底层方案1.1 机械臂类机械臂类的控制器发展较…

项目的ar指什么_AR眼镜显示测评标准解读——概述

AR眼镜检测哪些AR眼镜作为近眼显示设备的一种&#xff0c;运用其显示系统实现了虚拟信息与真实世界相叠加的效果&#xff1b;AR眼镜显示性能指标影响着AR产品实际的体验效果。因此&#xff0c;如何客观评价AR眼镜显示技术指标尤为重要。AR眼镜的性能特征和技术参数主要包括光学…

我的JAVA

一、了解Java Java是一门重编译语言&#xff0c;它本身就包含了许多类库、特性&#xff0c;再加上它所衍生出来的相关产品&#xff0c;是一个很庞大的语言体系&#xff0c;拥有无数分支&#xff0c;核心是JDK和JRE。 JDK&#xff0c;英文全称是Java Development Kit&#xff0c…

11下滑半个屏幕_努比亚发布手表手机:柔性屏幕,体积感人

2月26日凌晨&#xff0c;努比亚在MWC2019展会上召开新品发布会&#xff0c;全新的柔性屏“腕机”努比亚α正式与我们见面。努比亚α采用一块960*192分辨率的4英寸柔性屏&#xff0c;视野比手表类产品更广阔。同时为了让弯折的过程中不易出现起皱等问题&#xff0c;努比亚还使用…

Java-02

JAVA工作方式 源程序(myProgram.java) – > 编译(javac myProgram.java) -> JAVA字节码(myProgram.class) ->运行(java myProgram) 指令&#xff1a; 编译时&#xff1a;javac(compiler) 文件名运行时&#xff1a;java 文件名 JAVA的程序结构 源文件>类>方法&…

开机一直转圈_电脑开机后网络一直转圈,程序也打不开?

问题描述&#xff1a;最近&#xff0c;笔记本电脑开机之后&#xff0c;网络图标一直转圈&#xff0c;任何应用程序也打不开&#xff0c;开机关机还是可以的&#xff0c;之前是偶尔发生这种情况&#xff0c;然后重启一下或许就行了&#xff0c;但最近每次开机都是这个情况&#…

19生成材料清单_SOLIDWORKS 钣金装配体材料明细表扩展应用

【问题描述】&#xff1a;我们都知道&#xff0c;SOLIDWORKS装配体可以直接生成材料明细表&#xff0c;我们可以通过材料明细表查看详细的零件属性。例如零件名称、数量和材质等等。对于只包含钣金零件的装配体&#xff0c;我们是否可以在装配体材料明细表中表示钣金零件的展开…

http请求502_从知乎页面的502说一说测试人员应该知道的HTTP协议状态码!

从3.22开始&#xff0c;知乎网站的运行就出问题&#xff0c;总是弹出502页面。到3.23&#xff0c;竟然更大面积的出现502&#xff0c;甚至连手机APP的界面也是如此。那么当这种情况出现的时候&#xff0c;站在用户的立场上&#xff1f;他们怎么能够知道这是怎么回事儿&#xff…

docker 封装sql_docker封装mysql镜像

docker封装mysql镜像发布时间&#xff1a;2020-03-13 12:18:07编辑&#xff1a;admin阅读(967)一、概述直接使用官方的镜像docker pull mysql:5.7但是mysqld.cnf并没有优化&#xff0c;还是默认的。二、封装镜像创建目录# dockerfile目录mkdir -p /opt/dockerfile/mysql# 持久化…

怎么看vray渲染进度_3dmax渲染怎么看渲染时间

回答&#xff1a;如果你用VRAY渲染器的话&#xff0c; 按下F10在渲染选项卷展栏里--渲染器--VRAY系统---帧标记勾选,后面的文字是very的版本信息时间等&#xff0c;你可以对这些文字进行修改&#xff0c;那个rune time&#xff0c;是渲染时间。【3DMAX 2009最终渲染输出设置参数…

mysql binlog 订阅_数据库binlog订阅和消费组件canal快速入门

一、什么是canal1.定位Canal是阿里巴巴开源的一款基于mysql数据库binlog增量日志分析提供数据订阅和消费功能的组件2.原理Canal模拟MySQL Slave协议&#xff0c;将自己伪装成MySQL Slave&#xff0c;将Master发送dump协议Master将binlog同步到Slave(这里是Canal)Canal解析binlo…

工具系列:TensorFlow决策森林_(8)组合决策森林和神经网络模型

文章目录 介绍安装 TensorFlow Decision Forests导入库数据集模型结构模型训练评估决策森林下一步是什么&#xff1f; 介绍 欢迎来到TensorFlow Decision Forests&#xff08;TF-DF&#xff09;的模型组合教程。本教程将向您展示如何使用通用的预处理层和Keras函数式API将多个…

python 调用不存在的方法 统一处理_提取不重复数据在Excel、SQL与Python中的处理方法...

村长今天跟大家简单分享一下如何在Excel、SQL和Python中用不同的方法提取不重复值(数据去重)。一、Excel1.1、函数法(数组公式)函数公式&#xff1a;IFERROR(INDEX(A:A,SMALL(IF(MATCH($A$2:$A$16,$A$2:$A$16,0)ROW($1:$15),ROW($2:$16),9^9),ROW(A1))),"")1.2、技巧…

yum安装mysql5.7 简书_阿里云服务器(centos7.3)上安装jdk、tomcat、mysql、redis

前言:平时我们敲的项目&#xff0c;只能在本地浏览&#xff0c;不论项目写得怎么样只有自己看得到&#xff0c;只有发布到了云服务器&#xff0c;别人才能访问得到。学习之路就是这样&#xff0c;当别人能访问自己的项目时&#xff0c;会更有成就感&#xff0c;所以接下来就一起…

python绘制四边螺旋线代_解决python彩色螺旋线绘制引发的问题

彩色螺旋线的绘制代码如下&#xff1a;import turtleimport timeturtle.pensize(2)turtle.bgcolor(black)colors [red, yellow, purple, blue]turtle.tracer(False)for x in range(400):turtle.forward(2*x)turtle.color(colors[x % 4])turtle.left(91)turtle.tracer(True)tim…

idea创建java项目目录结构_用IDEA创建一个简单的Maven的JavaWeb项目

1.项目环境IDEA&#xff1a;2016.2JDK&#xff1a;1.8.0_76Maven&#xff1a;3.2.52.File-->New-->Project-->Maven3.选择Project SDK&#xff1a;1.8&#xff0c;然后勾选下方的Create from archetype&#xff0c;选择maven archetype webapp&#xff0c;点击Next4.填…

jmeter java性能_jmeter java性能测试

本篇文章主要讲解jmeter如何测试java请求&#xff0c;以项目中某个接口为例&#xff0c;请求数据为post&#xff0c;返回也为post1&#xff1a;新建maven工程&#xff0c;pom文件为1 2 xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd…

ckeditor java 上传_java使用CKEditor实现图片上传功能

java如何使用ckeditor实现图片上传功能&#xff0c;具体内容如下1.根据实际需要下载指定的ckeditor2.删除文件ckeditor/plugins/image/dialogs/image.js预览框中文本内容&#xff0c;并修改hidden属性值为显示上传选项卡删除image.js中包含在双引号中的上述文本将image.js中的h…