代码说明:提供一个微服务实例
创建两个模块:micro-provider:服务提供者,micro-consumer:服务消费者
micro-consumer可以有很多个,去消费。
1、常见micro-provider的工程:
1.1、引入相关的依赖如下
1.2、配置一些属性的配置信息:
1.3、提供一个domain的UserInfo的实体类:用户信息
类的结构就是get和set方法的结构
1.4、提供一个mapper的接口:
1.5、在主类里面加上MapperScan的注解,去把mapper接口生成的代理实现类去交给Spring容器管理。
1.6、由于接口会形成映射的,由于是单表操作的就不去写xml文件了。直接用注解的方式,代码如下:
1.7、新建一个service接口和实现类,代码如下:
1.8、新建一个controller,由于provider是要提供服务的。由于服务是rest风格的。所以说在spring4.3以后出现一个统一接口的注解@RestController
上面就是一个简单的springBoot应用就搭建成功了。
1.9、运行下上面的应用:
访问的结果如下 :是一个json的格式。因为它默认是使用jackson来序列化对象的。
restAPI来源于controller里面提供的路径。SpringBoot是一个入门的微框架。springBoot的项目就可以称之为简单的微服务应用。
2、在建一个micro-consumer的springBoot项目,因为它相当于一个前端的应用,所以依赖只要是一个web就可以了。既然是前端的服务,只需要提供json字符串就可以了。
2.1、新建一个vo->userVo的实体类用于给前台展示的,代码如下:
2.2、在微服务中应用通信的两种方式
A、RestTemplate
写一个配置类来获取RestTemplate对象,代码如下:
package com.boot.micro.demo.microconsumer.config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootConfiguration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
客户端通过RestTemplate的一个模板完成了对rest风格的调用,代码如下:
package com.boot.micro.demo.microconsumer.controller;
import com.boot.micro.demo.microconsumer.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class UserWrapController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("warp/user/{id}")
public UserVo getUser(@PathVariable("id") Integer userId){
return restTemplate.getForObject("http://localhost:8080/user/"+userId,
UserVo.class);
}
}
现在运行下客户端,然后访问下:
vo的实体类中的字段也可以不和提供服务的项目中的实体类的属性一样也可以,只要能够映射成一样就可以,代码如下:
再次运行下:
提问:如果micro-provider部署了三台服务器的话,客户端来调用,到底调用的是哪一个呢?这就涉及到了,多服务实例部署的时候就涉及到了负载均衡。所以说上面的方式是做不了负载均衡的。
负载均衡:让很多的实例去减少原有服务的压力然后把它做成了多个节点部署了多个节点,从而减少原有一个服务实例的压力。能力越强的承担的越大。
如果想要做负载均衡的话,需要把micro-provider定义一个应用名称:
然后把micro-provider配置三台:
把上面的三个微服务的实例给启动起来:
如果想要做负载均衡的话,用上面的方式是不行的,因为端口不一样了,上面的方式是写死的方式的。如果想要做负载均衡的话,必须引入一个负载均衡框架,这三个微服务实例是有注册的。然后客户端才能去发现的。需要有一个路由,来路由上面的三个微服务实例的才行。
1、加入服务注册中心,要把服务发现组件加进来才行,需要把服务的地址放到服务注册中心上去。正常的情况是客户端去访问哪一个服务端的地址是不知道的,而且为了保证服务端的的安全,不可能把服务端的ip地址告诉客户端。zookeeper其实是一个协调服务的一个组件。没有什么具体业务功能的实现。在zk中有watcher机制(有点类似于javaWeb中的监听器)和节点类型
下面的图是发布和订阅的模式。客户端去服务注册中心去提取列表,然后去做整个的负载均衡。
1、引入springCloud的依赖管理:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、引入zookeeper
<!--引入zookeeper-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-all</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
3、配置zookeeper:
4、如果想要被客户端发现的话,需要加上一个注解:
5、然后分别去启动下服务端的三个实例:
这个就是把三个微服务的实例注册上了zookeeper上了。
每个节点的内容如下:name为provider。id:是每一个节点的uuid的值。
address是本机的名字,也就是代表主机。port:8081。在每一个节点都已经记录好了这些内容的。最重要的是端口号和ip地址。
6、客户端也需要引入zookeeper的依赖:
客户端就可以运用zookeeper中的ribbon的负载均衡机制
ribbon当中其实有两个组件:httpclient(客户端调用)和loadbalancer(负载均衡器,因为它是从客户端拉取到可用的服务列表)
loadbalancer:这个自动有负载均衡策略的。它 针对SpringCloud所有的服务发现都可以来做的。
7、客户端的配置文件的配置如下:
8、客户端的主类函数如下,
9、由于客户端是发现zookeeper上的服务列表的,所以也需要加上启用服务发现的注解,代码如下:
10、然后启动消费端,连续访问6次:
下面的结果就是轮巡的方式做了负载的。
服务端每个节点都打印两条sql.
上面的方式就可以做到了负载均衡。
第三种方式:
1、加上@LoadBalanced注解
这种方式默认的方式也是轮巡的方式。
下面的接口里面是负载均衡的机制:这个接口里面有随机的策略,重试的策略。
轮巡策略,权重策略。
总结:在微服务中服务与服务的通信是通过restf风格的方式来进行通信的,上面的方式是ribbon加上restTemplate方式来实现的,ribbon在微服务中做客户端的负载均衡充当了重要的角色。服务端的负载均衡可以通过nginx来做。