一、zookeeper作为注册中心
1、服务端
先写pom文件,由于zookeeper自带slf4g为了防止一些冲突需要剔除一些jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
<version>3.4.7</version>
</dependency>
编写yml文件
spring:
application:
name: cloud-zookeeper-payment # 服务名
cloud:
zookeeper:
connect-string: 127.0.0.1:2181 # 注册中心的地址
编写业务类:
@RestController
public class PaymentController {
@Value("${server.port}") // 获取配置文件中的端口号
private String serverPort;
@GetMapping(value = "payment/zk")
public String paymentzk(){
// 调用成功后就返回一个字符串
return "SpringCloud with Zookeeper"+ serverPort+UUID.randomUUID().toString();
}
}
主启动类:
@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现
public class MainZookeeper {
public static void main(String[] args) {
SpringApplication.run(MainZookeeper.class, args);
}
}
2、消费端
pom文件的内容和服务端的主要内容一致,yml也与服务端的配置文件相似(修改端口号、服务名称)。
@RestController
public class Zcontroller {
public static final String invoke = "http://cloud-zookeeper-payment"; // 这里写服务端的服务名称
@Resource
private RestTemplate restTemplate;
@GetMapping(value = "consumer//payment/zk")
public String paymentInfo(){
return restTemplate.getForObject(invoke+"/payment/zk", String.class);
}
}
这里用到的一个restTemple配置类在前面的eureka中有详细的介绍,这里不再赘述。
主启动类:
@SpringBootApplication
public class Zconsumer {
public static void main(String[] args) {
SpringApplication.run(Zconsumer.class, args);
}
}
TIP:这样在zookeeper中创建的是什么节点?
zookeeper中一共有四种节点:临时节点、有序临时节点、永久节点、有序永久节点。在zookeeper中创建的属于临时节点,一旦无法正常检测心跳的时候,就会删除节点,这样保证了数据的一致性,属于cp分支。
二、consul作为注册中心
首先需要下载consul,下载完成以后在当前目录执行命令进行启动consul
consul agent -dev # 启动consul 默认端口8500
1、服务端
首先在pom文件中导入consul相关的包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
编写yml文件
server:
port: 8085
spring:
application:
name: cloud-consul-provider
cloud:
consul:
discovery:
service-name: ${spring.application.name}
host: localhost
port: 8500 # 默认是8500端口
业务类:
@RestController
public class payment {
@GetMapping(value = "payment/consul")
public String paymentzk(){
// 调用成功返回字符串
return "SpringCloud with consul"+UUID.randomUUID().toString();
}
}
主启动类不需要添加额外注解,不再赘述。
2、消费端
pom文件中也需要导入和服务端相同的jar包,yml文件也相似(修改端口号、服务名)。
业务类:
@RestController
public class Zcontroller {
public static final String invoke = "http://cloud-consul-provider"; // 这里是服务名称
@Resource
private RestTemplate restTemplate;
@GetMapping(value = "consumer/payment/consul")
public String paymentInfo(){
return restTemplate.getForObject(invoke+"/payment/consul", String.class);
}
}
主启动类也没有额外的注解。consul也是一个cp分支的分布式框架。
三、cap理论
1. cap中,C指的是强一致性,A指的是一致性,P指的是分区容错性。关注的重点是数据并非整体程序的架构。一个分布式系统是不可能同时满足以上三种要求的,最多同时满足两个,所以分成了三大类:
CA:单点集群,满足一致性,可用性的系统,通常在可扩展性方面不太强
CP:满足一致性,通常性能不太高。
AP:满足可用性,通常对一致性要求低一些。
2. 三种注册中心的对比
四、Ribbon
ribbon是一个负载均衡的客户端组件,ribbon在工作的时候分成两步:1.选择同一区域内负载较少的服务器;2.根据用户的选择策略,选择一个注册地址。
ribbon自带的7种选择策略:
1. RoundRobinRule 轮询。
2. RandomRule 随机。
3. RetryRule 先根据轮询策略获取服务,如果获取服务失败在指定时间内进行重试。
4. WeightedResponseTimeRule 根据权重选择。
5. BestAvailableRule 先过滤多次故障的服务,然后选择一个并发量最小的服务。
6. AvailabilityFilteringRule 先过滤掉故障实例,在选择并发比较小的。
7. ZoneAvoidanceRule 默认规则,符合判断server所在区域的性能和可用性选择服务器。
关于ribbon全在 IRule 这个接口中
public interface IRule{
// 选择服务器
public Server choose(Object key);
// 设置服务器
public void setLoadBalancer(ILoadBalancer lb);
// 获取服务器
public ILoadBalancer getLoadBalancer();
}
如何更换ribbon的策略
首先需要创建一个包,这个包不能在@ComponentScan注解扫描的范围,然而 @SpringBootApplication 注解中包含@ComponentScan注解所以不能放在同一个包内,如图所示创建包
创建一个配置类
@Configuration
public class MyselfRule {
@Bean
public IRule myRule(){
return new RandomRule(); // 定义用什么机制
}
}
然后在主启动类添加注解
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(configuration = MyselfRule.class, name = "CLOUD-SERVICE") // 配置类的类名,服务名称
public class OrderMain {
public static void main(String[] args) {
SpringApplication.run(OrderMain.class, args);
}
}