Springboot2.0+SpringCloud的搭建 以及常见问题解决

最近公司的项目有一个是类似于集成功能的一个平台的实现,各个子系统的用户管理都需要在集成的平台上进行操作,因为一些不可抗拒因素,平台对用户管理的操作 是通过ajax发送请求来完成的,这样也出现了一个问题,就是当我一个子系统项目出现了报错500的时候,我本地的数据库仍然修改了用户相关的信息,也就导致了平台数据库的数据和子系统数据库的数据不同步的问题。所以就需要解决分布式事务,所以自己根据慕课网的一些视频资料先来使用Springcloud搭建一个分布式的项目,但是因为大部分的资料都是Springboot1x 所以项目实际的操作过程中还是出现了很多问题 在这里记录一下。

什么是springcloud

springcloud 是很多种组件的整合,基于Sringboot构建的,它的版本号也很有意思 是根据伦敦的地铁站名命名的,而且不同版本的springcloud引用的依赖是不太一样的。在我的这个测试的项目中主要是用到了以下的几个组件

  • Eureka(服务注册中心)
  • Zuul(网关)
  • Hytrix(断路器)
  • Feign(声明式web service客户端)

实例

项目的思路也比较明确

  • 一个注册中心registry
  • 网关gloxy
  • 两个服务 User 和 Order 然后通过feign 使用User来调用Order服务
  • Hytrix可以单独部署的 我是和注册中心放到了一起
    项目结构如图;


    项目结构

    可以看到还有一个service 这个包之后用到的时候会再说,

注册中心的创建

首先创建registry pom文件引入依赖

  
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix-dashboard
        
        
            org.springframework.boot
            spring-boot-starter-security
        
        
            com.emp.test
            service
            1.0-SNAPSHOT
        
        
            com.emp.test
            transcation
            1.0-SNAPSHOT
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    
 
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

server的配置也是比较简单的 在yml文件中修改一下端口号 使用security来配置一下用户名和密码就可以,详细的配置文件如下

server:
  port: 8761

spring:
  application:
    name: registry
  security:
    user:
      name: zhou
      password: 12345678
  freemarker:
    prefer-file-system-access: false


eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    serviceUrl:
      defaultZone: http://zhou:12345678@localhost:${server.port}/eureka/

2.0的security配置也和之前不太一样了 register-with-eureka: false fetch-registry: false这两个配置 是为了防止server自己注册自己,禁止以下就好了 prefer-file-system-access是因为有些情况写会因为freemarker的原因 无法显示eureka的首页,当然不显示首页的原因 还可能是因为springcloud启动设置的问题 这个在后边会单独解决一下。

yml文件配置好之后 再在启动项中 添加

@SpringBootApplication
@EnableEurekaServer
@EnableHystrixDashboard
public class RegistryApplication {

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

    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

getServlet这个方法是因为在2.0在使用的时候 直接启动访问hystrix 会显示一个no connct的报错,具体的我忘记截图了 项目不会报错 页面上不会显示监控的效果 加上这个方法之后就ok了。
在2.0中因为security默认启用了csrf检验,要在eurekaServer端配置security的csrf检验为false。
所以在repostory中新建一个config文件

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        super.configure(http);
    }
}

不然会报错

ERROR 11612 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : *****:***** - was unable to send heartbeat!

这样注册中心就完成了 接下来 完成网关的创建

zuul网关的创建

同样 先引入pom文件

 
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-zuul
        
  
            org.springframework.boot
            spring-boot-starter-test
            test
        
    
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

然后再配置文件中进行配置

server:
  port: 8888

spring:
  application:
    name: proxy
eureka:
  client:
    serviceUrl:
      defaultZone:  http://zhou:12345678@localhost:8761/eureka

zuul:
  routes:
    userApi:
      path: /test/**
      stripPrefix: false
      serviceId: user

management:
  endpoints:
    web:
      exposure:
        include: ["health","info","hystrix.stream"]

配置端口号 application name 和注册中心的路径
zuul的那个配置是指我/test/**的所有连接 都会被当做是application name为user的服务下的链接地址,management的配置呢是用于hytrix的也是用来解决显示没有链接的问题的
然后在启动类中

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ProxyApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProxyApplication.class, args);
    }
}
服务的创建

我创建了两个服务 一个是User 一个是Order 需要User可以调用Order的服务,用的jpa和h2的内置数据库 没什么可记录的 也可以用jdbc和别的数据库来写自己的服务 主要是在User的服务中心 使用feign,引入依赖

   
            org.springframework.cloud
            spring-cloud-starter-hystrix
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            org.springframework.cloud
            spring-cloud-starter-feign
            1.4.6.RELEASE
        

配置文件

server:
  port: 8001

spring:
  application:
    name: user

eureka:
  client:
    serviceUrl:
      defaultZone: http://zhou:12345678@localhost:8761/eureka/

然后新建一个feignClient的接口 用来调用Order的方法

@FeignClient(value = "order",path = "/order/test")
public interface OrderClient extends OrderService {
    @GetMapping("/{id}")
    OrderDto getMyOrder(@PathVariable(name = "id")Long id);
}

然后再order的服务中 有一个对应的order/test/{id}Requestmapping就可以了 我写的方法如下

  @RequestMapping("/{id}")
    public OrderDto getMyOrder(@PathVariable(name = "id")Long id){
        Order order = orderService.getOrderById(id);
        OrderDto orderDto = new OrderDto();
        orderDto.setDetail(order.getDetail());
        orderDto.setTitle(order.getTitle());
        orderDto.setOrder_id(order.getOrder_id());
        return orderDto;
    }

可以看到这两个方法中 我都用到了一个OrderDto的类,
这个类就是我放在service中的类
就是把两个服务中 都会用到的实体类 给提取出来 然后在pom文件中引入包就可以了。
当然想法是比较好的 结果实际启动项目的时候就发生了报错 因为在不使用DTO的时候 项目已经顺利跑起来了 那么就是我DTO的引入问题,后来经过一系列的修改和测试 最后在修改了Registry的启动后好用了,我是把最外的项目transcation作为serverparent项目。

   com.emp.test
    transcation
    pom
    1.0-SNAPSHOT
    
        service
    

然后加上了

    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.5.RELEASE
    

然后将registry中的内容修改为

   
        com.emp.test
        transcation
        1.0-SNAPSHOT
         
    

然后启动四个项目


登录界面

首页

Hystrix

一个简单的Sprinboot+Springcloud的项目就搭建完成了

你可能感兴趣的:(Springboot2.0+SpringCloud的搭建 以及常见问题解决)