首页 > 其他分享 >springCloud-复习

springCloud-复习

时间:2023-03-21 11:15:16浏览次数:40  
标签:return 复习 springCloud public user provider id class

Mybatis-plus依赖:1是mybatis-plus-boot-starter本身的依赖,2是mysql-connector-java驱动,3是druid-spring-boot-starter连接池,
4是mybatis-plus-generator生成器。
父项目的<dependencyManagement>只是引入的管理,并不会做任何引入,所以在子项目必须再引入一遍。
!-- 资源引入 ,把src/main/java下的xml文件,打包的时候,打包到src/main/resources下面-->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
backend-common不在tomcat里面运行,给别人使用的公共模块。
@RunWith(SpringRunner.class)
@SpringBootTest     //写@Test时候,就可以依赖注入Mapper了。
public class PplicationTests {
    @Test
    public void contextLoads() {
    }
}

//其他类可以继承PplicationTests,也可以依赖注入Mapper了。
public class Test extends PplicationTests {
    @Autowired
    private MoocBackendUserTMapper mapper;

    public void select(){
    }
}
Lombok是插件,@Data是get set方法的注解。@Data注解是在编译时候生成set get方法,但是开发时候是在编译之前,为了可以使用get set方法,就要用到Lombok插件。
@Builder注解,就可以使用User.build().id().name().age().build();   build模式。
@Slf4j注解,就可以直接使用log.info(“......”);
parent工程里面的dependencies,子工程都会有。parent的dependencyManagement子工程不会有,需要再引入一遍,只是管理版本号。

module A和module B之间用dependencie引用,跟正常引用junit包一样,才可以使用它里面的方法。parent里面通过modules引入其他所有module是正常写法,只要是父子工程就必须这么写。

module A通过 dependencie引入module B,
module C只需要 dependencie引入module A,就可以同时dependencie module A和module B。
module C,module B,module A都有parent的包,不会冲突,会依据最短路径,只引入一个包。
@MapperScan(basePackages = {"com.mooc.meetingfilm.film.dao"}), MapperScan最好每个模块都加一个。
eureka server: 
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

server:
    port: 8761
eureka:
    instance:
        hostname: localhost
        prefer-ip-address: true
    client:
        register-with-eureka: false
        fetch-registry: false
    service-url:
        defaultZone: http://localhost:8761/

@EnableEurekaServer
@SpringBootApplication
public class BackendEurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(BackendEurekaServerApplication.class, args);
    }
}    就可以了。
Eureka Client:生产者和消费者都要配置 

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

server:
    port: 8201
eureka:
    client:
        service-url:
            defaultZone: http://localhost:8761/eureka/
spring:
    application:
        name: hello-service-consumer

@EnableFeignClients
@EnableDiscoveryClient  // DiscoverClient可以集成大部分注册中心
// @EnableEurekaClient  只对Eureka使用
@SpringBootApplication
public class BackendShowConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(BackendShowConsumerApplication.class, args);
    }
}
消费端远程调用:
@Service
public class ConsumerServiceImpl implements ConsumerServiceAPI{
    @Autowired
    private RestTemplate restTemplate;  //依赖注入

    @Override
    public String sayHello(String message) {  
        String result = restTemplate.getForObject
        ("http://hello-service-provider/provider/sayhello?message=111", String.class);
        return result;
    }
}
消费端远程调用:
@Service
public class ConsumerServiceImpl implements ConsumerServiceAPI{
    @Autowired
    private RestTemplate restTemplate;  //依赖注入

    @Override
    public String sayHello(String message) {  
        String result = restTemplate.getForObject
        ("http://hello-service-provider/provider/sayhello?message=111", String.class);
        return result;
    }
}
@Configuration
public class RestConfig {
    @Bean //注册成bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();   //被依赖注入
    } 
}
Eureka心跳是30s,90s没有收到心跳就剔除。Eureka退出时会发生cancel命令给server。Kill-9是不会发生cancel的。

Eureka client会缓存注册信息,30s定期更新,

Ribbon:客户端的负债均衡,需要有serverList。

@GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
    // http://localhost:7900/simple/,microservice-provider-user是注册到eureka之后的一个虚拟主机名(页面有,microservice-provider-user工程的虚拟主机名)。
     //microservice-provider-user工程的配置文件中spring.application.name中定义。
    // VIP virtual IP。不再是通过服务提供者的ip和端口访问了。
    // HAProxy Heartbeat
    //spring:application:name:microservice-provider-user
    return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
  }

  @GetMapping("/test")
  public String test() {
      //如果microservice-provider-user微服务有多个,可以看出命中的是哪个ip端口
    ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
    System.out.println("111" + ":" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":" + serviceInstance.getPort());

    ServiceInstance serviceInstance2 = this.loadBalancerClient.choose("microservice-provider-user2");
    System.out.println("222" + ":" + serviceInstance2.getServiceId() + ":" + serviceInstance2.getHost() + ":" + serviceInstance2.getPort());

    return "1";
  }
@SpringBootApplication
@EnableEurekaClient
public class ConsumerMovieRibbonApplication {

  @Bean
  @LoadBalanced//就一个注解。@LoadBalanced整合了ribbon,让RestTemplate具备负载均衡的能力
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

@Bean
  public IRule ribbonRule() {
    return new RandomRule(); //随机选取一个微服务,也可以自己定义路由规则。  }
}

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

Iping: NIWSDiscoverPing,PingURL, DummyPing,NoOpPing,

Hystrix : 熔断,提高系统可用性,避免级联故障。

两种命令模式:HystrixCommand和HystrixObservableCommand。

GroupKey和CommandKey。请求缓存。

目前使用eureka server完成了服务注册和服务发现,ribbon完成了客户端负载均衡。如果服务提供者的响应很慢那么服务消费者会强制等待,一直等到http请求超时,如果服务消费者还是其他的服务提供者,那么就会产生级联的雪崩。

超时机制:等待几秒还是没响应,就直接返回了。

断路器模式:A如果有大量的超时,B一直去请求A是没有意义的,不再去请求A直接返回异常。保证B不会拖死。

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker  //启用断路器
public class ConsumerMovieRibbonApplication {

  @Bean
  @LoadBalanced  //ribbon的客户端负载均衡
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

  public static void main(String[] args) {
    SpringApplication.run(ConsumerMovieRibbonApplication.class, args);
  }
}
@RestController
public class MovieController {
  @Autowired
  private RestTemplate restTemplate;

  //http://localhost:8010/movie/1
  //查看hystrix的状态http://localhost:8010/hystrix.stream
  //第一次会进fallbackMethod方法,后面走microservice-provider-user。因为Hystrix默认超时时间是1秒。
  //microservice-provider-user挂了就进fallbackMethod
  @GetMapping("/movie/{id}")
  @HystrixCommand(fallbackMethod = "findByIdFallback")  //参数和返回值类型一样,当用户微服务挂了就走fallbackMethod。进入了fallbackMethod不代表断路器打开。
  public User findById(@PathVariable Long id) {
    return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
  }

  public User findByIdFallback(Long id) {
    User user = new User();
    user.setId(0L);
    return user;
  }
}

Feign:是一个HTTP客户端。简化了HTTP调用方式。Feign整合了Ribbon和Hystrix。Feign只有接口。

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients  //Feign的客户端
public class ConsumerMovieFeignApplication {
  public static void main(String[] args) {
    SpringApplication.run(ConsumerMovieFeignApplication.class, args);
  }
}
@RestController
public class MovieController {
  @Autowired
  private UserFeignClient userFeignClient;
/*  原来是通过restTemplate来调用
  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
        return this.restTemplate.getForObject(this.userServicePath + id, User.class);
  }*/
  
  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
    return this.userFeignClient.findById(id);
  }

  @GetMapping("/test")
  public User testPost(User user) {
    return this.userFeignClient.postUser(user);
  }
}
//Configuration2作为他的配置文件
@FeignClient(name = "xxxx", url = "http://localhost:8761/", configuration = Configuration2.class)
public interface FeignClient2 {
  @RequestMapping(value = "/eureka/apps/{serviceName}")
  public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName);
}
@Configuration
public class Configuration2 {
  @Bean
  public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
    return new BasicAuthRequestInterceptor("user", "password123");
  }
}

Feign整合Hystrix:

@RestController
public class MovieController {
  @Autowired
  private UserFeignClient userFeignClient;

  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
    return this.userFeignClient.findById(id);
  }
}
@FeignClient(name = "microservice-provider-user", fallback = HystrixClientFallback.class)
public interface UserFeignClient {
  @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
  public User findById(@PathVariable("id") Long id);
}
@Component
public class HystrixClientFallback implements UserFeignClient {
  @Override
  public User findById(Long id) {
    User user = new User();
    user.setId(0L);
    return user;
  }
}

feign整合hystrix_factory

@RestController
public class MovieController {
  @Autowired
  private UserFeignClient userFeignClient;

  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
    return this.userFeignClient.findById(id);
  }
}
@FeignClient(name = "microservice-provider-user", /*fallback = HystrixClientFallback.class, */fallbackFactory = HystrixClientFactory.class)
public interface UserFeignClient {//请求microservice-provider-user的/simple/{id}方法。失败回调调用的是HystrixClientFactory的findById方法
  @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
  public User findById(@PathVariable("id") Long id);
}
@Component
public class HystrixClientFactory implements FallbackFactory<UserFeignClient> {
  @Override
  public UserFeignClient create(Throwable cause) {
    HystrixClientFactory.LOGGER.info("fallback; reason was: {}", cause.getMessage());
    return new UserFeignClientWithFactory() {
      @Override
      public User findById(Long id) {
        User user = new User();
        user.setId(-1L);
        return user;
      }
    };
  }
}

Feign默认使用的是JDK的HTTP方式,所以最好优化HTTP的方式,Apache HTTPClient是个不错的选择。OKHTTP也是可以的。

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

Feign的解压缩,可以优化网络带宽。

feign:
  hystrix:
    enabled: true
  httpclient:
    enabled: true
  compression:
    request:
      enabled: true
      mime-types: text/xml,application/xml,application/json
      min-request-size: 2048
    response:
      enabled: true

Zuul:网关,客户端只需要知道网关的ip和端口就可以了,网关知道后面微服务的ip和端口。Ribbon是客户端的负载均衡器,Zuul是服务端的负载均衡器。

使用http://192.168.88.1:7901/simple/1直接访问user微服务(7901是user的微服务地址),

http://192.168.88.1:8040/microservice-provider-user/simple/1(8040是zuul的端口,microservice-provider-user是user微服务的application:name)。通过zuul就可以访问user服务了。

经过zuul的请求都会通过hysitrcs包裹,所以zuul会有断路器功能。zuul还使用了ribbon做负载均衡。

Zuul过滤器:Zuul有4中过滤器,PRE,ROUTING,POST,ERROR。Pre先执行然后routing,然后post然后error.

pre是zuul请求别的微服务之前(鉴权),routing是请求过程中的(数据增强),post是请求到微服务之后可以添加一些header,error是抛异常了。也可以自定义过滤器。

@SpringBootApplication
@EnableZuulProxy     //使用这一个注解就可以注册到eureka,zuul要从eruka拉取注册的服务信息,
public class ZuulApplication {
  public static void main(String[] args) {
    SpringApplication.run(ZuulApplication.class, args);
  }
}
spring:
  application:
    name: microservice-gateway-zuul
server:
  port: 8040
eureka:
  client:
    service-url:
      defaultZone: http://user:password123@localhost:8761/eureka  
instance:
    prefer-ip-address: true
zuul:
  routes:
    abc:                            # abc随意,只要唯一就可以
      path: /user-path/**               # 使用user-path访问user微服务
      serviceId: microservice-provider-user        # 注册到eureka的服务的application名字
    
# http://localhost:8040/routes : 查看zuul代理的微服务
# {"/user-path/**":"microservice-provider-user","/microservice-provider-user/**":"microservice-provider-user"}
# 就可以使用zuul来代理user微服务:http://localhost:8040/microservice-provider-user/simple/1
# zuul的请求都用hystrix包裹:http://localhost:8040/hystrix.stream

Zuul拦截器:

@Slf4j
public class MyFilter extends ZuulFilter {
    @Override
    public String filterType() {//Filter类型
        return "pre";
    }

    @Override
    public int filterOrder() {//filter的执行顺序
        return 0;
    }

    @Override
    public boolean shouldFilter() {//是否要拦截
        return true;
    }

    @Override
    public Object run() throws ZuulException {// Filter的具体业务逻辑
        RequestContext requestContext = RequestContext.getCurrentContext();// ThreadLocal
        HttpServletRequest request = requestContext.getRequest();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String headName = headerNames.nextElement();
            log.info("headName:{}, headValue:{}", headName, request.getHeader(headName));
        }
        return null;
    }
}
@Configuration
public class ZuulConfig {
    @Bean
    public MyFilter initMyFilter(){
        return new MyFilter();
    }

    @Bean
    public JWTFilter initJWTFilter(){
        return new JWTFilter();
    }
}

Zuul的Hystics的降级处理:超时降级

//Zuul的Hystics的降级处理:超时降级
@Component
public class MyFallback implements FallbackProvider {
    //针对哪一个路由进行降级, return可以写 *
    @Override
    public String getRoute() {
        return "film-service";
    }

    //降级时处理方式
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }

            @Override
            public String getStatusText() throws IOException {
                return "OK";
            }

            @Override
            public void close() {
            }

            //业务降级处理方式
            @Override
            public InputStream getBody() throws IOException {
                BaseResponseVO responseVO = BaseResponseVO.serviceException(
                        new CommonServiceException(404, "No Films!~"));
                String result = JSONObject.toJSONString(responseVO);
                return new ByteArrayInputStream(result.getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

https://gitee.com/yw672530440/maven-spring-cloudm.git

Mybatis-plus依赖:1是mybatis-plus-boot-starter本身的依赖,2是mysql-connector-java驱动,3是druid-spring-boot-starter连接池,4是mybatis-plus-generator生成器。

标签:return,复习,springCloud,public,user,provider,id,class
From: https://www.cnblogs.com/yaowen/p/17239222.html

相关文章

  • SpringCloud——SpringCloud Alibaba Seata 原理与实战
    摘要主要讲解是分布式事务指事务的操作位于不同的节点上,需要保证事务的AICD特性。分布式事务顾名思义就是要在分布式系统中实现事务,它其实是由多个本地事务组合而成。对于......
  • SpringCloud——springcloud大厂面试问题
    摘要 毫无疑问,SpringCloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术。不过大多数讲解还停留在对SpringCloud功能使用的层面,其底层的很多原理,很多人可......
  • JAVA -适合新手和复习(Restart)
    作为22届专科生,在没有经历和学历的情况下找一份得体的工作 是多么“奢侈”,世上岂无千里马,人中难得九方皋.废话太多我们开始吧!JAVA从这里开始 Java的历史(不感兴趣直......
  • SpringMVC-lesson01-servlet复习2-2023-03-20
    1、欢迎页设置在web文件夹下新建form.jsp:input的类型是text,名字是:method。一旦输入add或delete提交,就会到HelloServlet进行跳转<%--CreatedbyIntelliJI......
  • nacos原理(一)Springcloud 配置中心接入原理&客户端拉取配置原理
    ​ 之前已经了解到Springcloud环境对bootstrap.yml加载的原理,也就是加载bootstrap的时机比较靠前。接下来简单研究下Springcloud环境中配置中心的加载以及动态更新原理。......
  • 【转载】中考一轮复习-云凌shapphire
    课程学习课程视频链接:https://www.bilibili.com/video/BV1RY411971Z文件链接文件转载自up主云凌的百度网盘文件摘要:中考数学一轮复习之二次函数-云凌Sapphire【讲义......
  • SpringAll(1-12)复习
    1-12复习详细解释Thymeleaf月springboot的关系Thymeleaf是一个现代化的Java模板引擎,它允许开发人员使用自然模板语言来创建动态网页。而SpringBoot是一个快速开发框架,它......
  • 快速带你复习html(超详细)
    此内容包含:html基础列表、表格媒体元素表单(重点)1、HTML基础目标:会使用HTML5的基本结构创建网页会使用文本相关标签排版文本信息会使用图像相关标签实现图文并......
  • SpringCloud-搭建eurekaServer
    Eureka介绍整体介绍背景:在传统应用中,组件之间的调用,通过有规范的约束的接口来实现,从而实现不同模块间良好的协作。但是被拆分成微服务后,每个微服务实例的网络地址都可......
  • 【链表】复习/刷题 记录
    leetcode203.RemoveLinkedListElements/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode......