springcloud H版+alibaba cloud 2

springcloud H版+alibaba cloud 2

  • 7,服务配置进集群
  • 8,actuator服务信息的完善
  • 9,服务的注册与发现
  • 10,springcloud整合zookeeper代替eureka
  • 11,consul
  • 12,ribbon负载均衡

接上一章的。。。那一大段代码。怎么来的全部下面有叙述

7,服务配置进集群

分别在两个服务下进行集群配置
springcloud H版+alibaba cloud 2_第1张图片

服务提供者集群搭建

创建8002提供者

将8001的全部粘贴过来,不用改application:
name

这时候对外暴露的服务需体现出负载均衡。所以这里

1,改8001 controller
在这里插入图片描述

在这里插入图片描述

2,8002同理

这时候5个服务启动。访问所有服务都正常。但是访问consumer,只能通过8001.。。。因为原程序restTemplete那里写死了

3,
在这里插入图片描述
还有必须开启restTemplete负载均衡功能

在配置类。。。加一个@loadbalance注解

springcloud H版+alibaba cloud 2_第2张图片

8,actuator服务信息的完善

其实就是服务名的改变

1,只暴露服务名,去掉主机名
2,你鼠标指到微服务名字。要显示ip。

1,

8001

springcloud H版+alibaba cloud 2_第3张图片

随便点开一个服务

然后把后缀info改成health。。。健康检查状态

现在是UP

2,

在这里插入图片描述

9,服务的注册与发现

springcloud H版+alibaba cloud 2_第4张图片

8001
修改controller

在这里插入图片描述

自己写个方法自测

springcloud H版+alibaba cloud 2_第5张图片

2,主启动类

在这里插入图片描述

启动就好

     eureka自我保护机制

默认自我保护是开启的。。。
7001
springcloud H版+alibaba cloud 2_第6张图片

8001

在这里插入图片描述
启动注册中心和8001,发现8001注册上去了。但是8001如果服务停了。再刷新eureka。。发现服务就没了。

10,springcloud整合zookeeper代替eureka

eureka基本淘汰。现在用zookeeper来代替

创建一个payment8004提供者注册进入zookeeper
在这里插入图片描述
pom文件,eureka换成zookeeper

version 2.2.2.RELEASE

yml

springcloud H版+alibaba cloud 2_第7张图片

启动类

springcloud H版+alibaba cloud 2_第8张图片
在这里插入图片描述

controller
springcloud H版+alibaba cloud 2_第9张图片

启动以后发现,没有报错。controller也可以正常使用

2,创建一个消费者注册进zookeeper

pom复制8004的

yml
springcloud H版+alibaba cloud 2_第10张图片

config和controller复制之前order80的

然后controller进行修改

springcloud H版+alibaba cloud 2_第11张图片

11,consul

1,下载consul
2,配置环境变量,把文件夹根目录配置进去
3,执行consul agent -dev启动consul

编码部分
pom.xml


    org.springframework.cloud
    spring-cloud-starter-consul-discovery
    2.1.0.RELEASE

application.yml

server:
  port: 8006
spring:
  application:
    name: consul-provider-payment
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}

controller

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
@Slf4j
public class PaymentController {
    @Value("${server.port}")
    private String serverport;
    @RequestMapping(value="/payment/consul")
    public String paymentConsul(){
        return serverport+"\t"+ UUID.randomUUID().toString();
    }
    
}

主启动类

package com.atguigu.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain8006 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8006.class,args);
    }
}

###consumer
1,pom.xml同上
2,application.yml改动端口号和服务名
3,启动类一样
4,增加一个config

package com.atguigu.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

5,业务类

package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderConsulController {
    public static final String PAYMENT_URL="http://consul-provider-payment";
    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/consul")
    public String paymentInfo(){
        String result=restTemplate.getForObject(PAYMENT_URL+"/payment/consul",String.class);
        return result;
    }

}

###eureka zookeeper和consul三个注册中心的异同
eureka:java编写,ap(高科用,分区容错)。对外暴露http 被springcloud集成

consul:go编写,cp(强一致,分区容错)。对外暴露http/DNS 被springcloud集成

zookeeper:java编写,cp(强一致,分区容错)。对外暴露客户端 被springcloud集成

zookeeper是临时节点还是持久节点?
都有。创建以后一直都在就是持久节点
服务停止则立即被剔除就是临时节点

12,ribbon负载均衡

它是客户端的负载均衡工具

ribbon暂时不被替换。可能未来会被loadbalacer替代

#ribbon和nginx的区别?
nginx是客户端请求。由nginx转发
ribbon是本地的负载均衡。本地实现rpc远程调用
ribbon属于进程内lb 。nginx属于集中式lb

eureka的pom文件没有引入ribbon为什么可以使用它?
因为新版的spring-cloud-start-netflix-eureka-client自己集成了ribbon

ribbon远程调用的实现就是负载均衡+RestTemplete

RestTemplete的ForEntity用法

编码

1,在ordermain80的controller里面加方法

//restTemplete的ForEntity
@GetMapping("/consumer/payment/getForEntity/{id}")
public CommonResultentity(@PathVariable("id")Long id){
    ResponseEntityentity=restTemplate.getForEntity(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    if(entity.getStatusCode().is2xxSuccessful()){
        return entity.getBody();
    }else{
        return new CommonResult<>(444,"操作失败");
    }
}

ribbon轮询算法。实现了IRule接口

一共七种
BestAvailableRule :选择一个最小的并发请求的server
AvailabilityFilteringRule :过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)
WeightedResponseTimeRule :根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低
RetryRule :对选定的负载均衡策略机上重试机制
RoundRobinRule:roundRobin方式轮询选择server
RandomRule:随机选择一个server
ZoneAvoidanceRule:复合判断server所在区域的性能和server的可用性选择server

###替换方法

1,替换80的consumer项目
2,ribbon的轮询替换不允许跟有@ComponentScan一起

3,新建包com.atguigu.myrule
4,新建类:MyselfRule

package com.atguigu.springcloud.myrule;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MySelfRule {
    @Bean
    public IRule myRule(){
        return new RandomRule();  //定义为随机
    }
}

5,主启动类

@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)

再访问localhost/consumer/payment/get/1

##负载均衡算法
rest访问次数%服务集群数=实际调用服务器位置下标。每次重启服务后,rest接口计数从1开始

RoundRobinRule底层用到CAS,比较并交换,自旋锁的方式

手写ribbon负载均衡

1,7001,7002集群启动
2,8001,8002微服务改造
3,80订单微服务改造

1,8001,8002的controller里加一个方法
//手写ribbon 负载均衡

@GetMapping(value="/payment/lb")
public String getPaymentLB(){
    return serverport;
}

2,注释掉applicationContextConfig里的@LoadBalanced注解
3,在order 80里新建包Lb,新建接口LoadBalacer

package com.atguigu.springcloud.lb;

import org.springframework.cloud.client.ServiceInstance;

import java.util.List;

public interface LoadBalancer {
    ServiceInstance instance(ListserviceInstances);
}

4,实现类 MyLB

package com.atguigu.springcloud.lb;

import org.springframework.cloud.client.ServiceInstance;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Component
public class MyLB implements LoadBalancer {
    private AtomicInteger atomicInteger=new AtomicInteger(0);
    public final int getAndIncrement(){
        int current;
        int next;
        do{
            current=this.atomicInteger.get();
            next=current>=2147483647?0:current+1;
        }while(!this.atomicInteger.compareAndSet(current,next));
        System.out.println("************next:"+next);
        return next;
    }
    @Override
    public ServiceInstance instance(List serviceInstances) {
        int index=getAndIncrement()% serviceInstances.size();
        return serviceInstances.get(index);
    }
}

5,controller

package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.lb.LoadBalancer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.URI;
import java.util.List;

@RestController
@Slf4j
public class OrderController {
    public static final String PAYMENT_URL="http://CLOUD-PAYMENT-SERVICE";
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private LoadBalancer loadBalancer;
    @Resource
    private DiscoveryClient discoveryClient;

    @PostMapping("/consumer/payment/add")
    public CommonResultcreate(@RequestBody Payment payment){
        return restTemplate.postForObject(PAYMENT_URL+"/payment/add",payment,CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResultget(@PathVariable("id")Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }

    //restTemplete的ForEntity
    @GetMapping("/consumer/payment/getForEntity/{id}")
    public CommonResultentity(@PathVariable("id")Long id){
        ResponseEntityentity=restTemplate.getForEntity(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
        if(entity.getStatusCode().is2xxSuccessful()){
            return entity.getBody();
        }else{
            return new CommonResult<>(444,"操作失败");
        }
    }
    //手写ribbon负载均衡
    @GetMapping(value="/consumer/payment/lb")
    public String getpaymentLb(){
        Listinstances=discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        if(instances!=null||instances.size()<=0){
            return null;
        }
        ServiceInstance serviceInstance=loadBalancer.instance(instances);
        URI uri=serviceInstance.getUri();
        return restTemplate.getForObject(uri+"/payment/payment/lb",String.class);
    }
}

你可能感兴趣的:(java)