项目总结springcloud、富文本、三级联动

1、富文本的使用
2、json类型的字段 可以使用转换成json保存进去
3、省市区三级联动 后端用pid得到list集合,前端发送请求
https://blog.csdn.net/NaMgAl_/article/details/79018146

依赖、配置文件

config动态配置

启动类加入
@EnableEurekaClient
@EnableConfigServer

<!--
        统一配置中心的客户端,注意没有 client
        -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!--配置文件动态刷新-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
server:
  port: 9999 #端口号

spring:
  application:
    name: travel-config #注册到eureka的服务名
  cloud:
    config:
      server:
        git: #访问的地址 仓库地址 +config文件夹+travel-config-name.yml
          uri: https://gitee.com/fengyabin/travel-config-2009.git
          search-paths: config  # 文件夹

#注册中心
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka #eureka服务地址
  instance:
    prefer-ip-address: true #显示 ip

读取配置文件

server:
  port: 7777
spring:
  application:
    name: travel-system
  cloud:
    config:
      uri: http://localhost:9999 #config服务的端口
      profile: datasource,redis,rabbitmq # travel-config-datasource
      name: travel-config #config服务的名称

mybatis使用

mybatis:
  type-aliases-package: xyz.fuqufyb.aec.entity #所有entity别名类的包
  mapper-locations: classpath:mapper/*.xml # mybatis映射文件
  configuration:
    map-underscore-to-camel-case: true  # 开启驼峰式命名

### Ribbon 配置
ribbon:
  # 连接超时
  ConnectTimeout: 2000
  # 响应超时
  ReadTimeout: 5000
hystrix:
  shareSecurityContext: true
  command:
    default:
      execution:
        isolation:
          thread:
            # 熔断器超时时间,默认:1000/毫秒
            timeoutInMilliseconds: 5000
#fastdfs 用于上传图片
fdfs:
  connect-timeout: 3000
  so-timeout: 3000
  thumb-image:
    width: 100
    height: 100
  tracker-list:
  - 101.132.226.166:22122

mybatisplus

<!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml # mybatis映射文件
  configuration:
    map-underscore-to-camel-case: true  # 开启驼峰式命名

启动类
@MapperScan(“com.springcloud.travel.aviation.dao”) 扫描mapper接口用于代理

Mapper接口继承 extends BaseMapper<Theme>
service接口继承extends IService<Theme>
serviceimpl extends ServiceImpl<ThemeMapper, Theme> implements service

config包

@Configuration
public class MyBatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }
}

实现分页

private QueryWrapper getQueryWrapper(Map<String, String> map) {
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            String themeType = (String) map.get("themeType");
//            String orderState = (String) map.get("state");
            // 判断是否为空
            if (!StringUtils.isEmpty(themeType)){
                queryWrapper.like("theme_type",themeType);
            }
//            if (!StringUtils.isEmpty(orderState)){
//                queryWrapper.like("order_state",orderState);
//            }
            return queryWrapper;

    }
 Page<Theme> pages = new Page<>();
        pages.setCurrent(Integer.parseInt(page));
        pages.setSize(Integer.parseInt(limit));

        //分页查询
        Page<Theme> themePage = themeService.page(pages,this.getQueryWrapper(map));

oepnfeign

 <!--        openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
 #开启feign的降级
feign:
  hystrix:
    enabled: true

启动类
@EnableFeignClients // 开启 openFeign
必须加参数名@RequestParam(“map”) ,否则无法绑定

//决定调用的服务TRAVEL-THEME 
@FeignClient(value = "TRAVEL-THEME",path = "/theme",fallback = ThemeFeignFallBack.class)
public interface ThemeFeign {

    /**
     * 主题管理的查询
     */
    @RequestMapping("/show")
    public TableResult<Theme> selectAllTheme(@RequestParam("map") Map<String, String> map);


    /**
     * 主题管理的增加
     */
    @RequestMapping("/add")
    public boolean add(@RequestBody Theme theme);

    /**
     * 主题管理的修改
     */
    @RequestMapping("/update")
    public boolean update(@RequestBody Theme theme);


    /**
     * 主题管理的删除
     */
    @RequestMapping("/delete")
    public boolean delete(@RequestParam("ids") String[]  ids);

}

fastdfs

需要加入webuploader包 引入文件

启动类
@Import(FdfsClientConfig.class)//fastdfs
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)//fastdfs
<!--fastdfs用于webupload上传-->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.26.1-RELEASE</version>
        </dependency>

thymeleaf 用于读取页面文件

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

RabbitMQ

 <!--用于发送 mq 消息的-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
//input output接口
@EnableBinding({ReceviedAPIRoutingChangeStream.class, LogOutPut.class})
public interface ReceviedAPIRoutingChangeStream {
	//交换机名称 用于接收消息
    @Input("apiroutingchange")
    SubscribableChannel input();

}
//接收消息还需要一个listener 交换机名称 ,能够接收传过来的APIRoutingMQBean
@StreamListener("apiroutingchange")
    public void apiMessage(APIRoutingMQBean apiRoutingMQBean){}
public interface LogOutPut {
	//交换机名称 发送消息 创建此接口send消息
    @Output("logqueue")
    MessageChannel out();
    //举例
 logOutPut.out().send(new GenericMessage<String>(objectMapper.writeValueAsString(loggerBean)));


}

Zuul

@PostConstruct的坑 执行此注解表示这个方法在服务启动时初始化,需要将
断路器 feign ribbon的配置注释掉,否则出现超时异常
启动类
@EnableCircuitBreaker //断路器
@EnableZuulProxy

 @PostConstruct
    public void init(){

        //得到缓存中所有api的key
        Set<String> allKeys = cacheFeign.findKeyByPartten("APINAME:*");
        System.err.println(allKeys);
        if (allKeys!=null&&allKeys.size()>0){
            for (String key : allKeys) {

                //通过key得到对象
                Map<Object, Object> objectObjectMap = cacheFeign.hGetAll(key);
                //保存到API_ROUTING_MAP_CACHE中
                API_ROUTING_MAP_CACHE.put(key,objectObjectMap);

            }
        }
        System.err.println(API_ROUTING_MAP_CACHE);


    }

动态路由

  //获取请求路径
        RequestContext currentContext = RequestContext.getCurrentContext();
         //实现动态路由 根据服务名 路径发送
//服务id   openapi-test01         currentContext.put(FilterConstants.SERVICE_ID_KEY,serviceId);
 //访问路径    /testservice/test01        currentContext.put(FilterConstants.REQUEST_URI_KEY,insideApiUrl);

事件监听器

@Autowired
     private ApplicationContext applicationContext;
     //推送事件 事件对象eventBean
      applicationContext.publishEvent(eventBean);
      //事件监听
       @EventListener
    public void send(EventBean eventBean) throws GeneralSecurityException, MessagingException {}
spring:
  application:
    name: openapi-zuul
  rabbitmq:
    host: 10.36.144.99
    username: lee
    password: lee
    virtual-host: /lee_virtual
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9999/eureka
management:
  endpoints:
    web:
      exposure:
        include: "*"  #打开所有的监控管理地址
zuul:
  routes:
    openapi-cache: "/*"

分布式和邮件报警

 <dependencies>


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--
        分布式任务核心依赖

        -->
        <dependency>
            <groupId>com.dangdang</groupId>
            <artifactId>elastic-job-lite-core</artifactId>
            <version>2.1.5</version>
            <!--
            我们使用的是 ZK 做锁,但是内部的依赖版本在此处不符合我们安装的 zk 版本,我们安装的 ZK 是 3.4.13 版本
            -->
            <exclusions>
                <exclusion>
                    <artifactId>curator-framework</artifactId>
                    <groupId>org.apache.curator</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.dangdang</groupId>
            <artifactId>elastic-job-lite-spring</artifactId>
            <version>2.1.5</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>


        <!--
        根据我们的 ZK 版本导入对一个的 curator,因为内置的zookeeper低于我们的 3.4.13 所以我们排除然后导入自己的版本

        -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.13.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>zookeeper</artifactId>
                    <groupId>org.apache.zookeeper</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.13.0</version>
        </dependency>
        <!--
        根据我们的 ZK 版本导入自己的依赖
        -->

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.13</version>
        </dependency>
        <!--
        邮件报警的依赖
        -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
    </dependencies>
@Configuration
public class MonitorConfig {

    @Value(("${elasticjob.regcenter.serverList}")) String serverList;
    @Value(("${elasticjob.regcenter.namespace}")) String nameSpace;
    @Value(("${elasticjob.corn}")) String corn;
    @Value(("${elasticjob.count}")) int shardingTotalCount;
    @Value(("${elasticjob.shardingparamters}")) String shardingparamters;
    /**
     * 分布式锁注册i中心
     */
    @Bean(initMethod = "init")
    public ZookeeperRegistryCenter zookeeperRegistryCenter(){
        //ZookeeperConfiguration 设置集成和名字
        ZookeeperConfiguration zookeeperConfiguration=new ZookeeperConfiguration(serverList,nameSpace);
        zookeeperConfiguration.setConnectionTimeoutMilliseconds(10000);
        zookeeperConfiguration.setMaxRetries(5);
        //直接创建一个ZookeeperRegistryCenter
        ZookeeperRegistryCenter zookeeperRegistryCenter = new ZookeeperRegistryCenter(zookeeperConfiguration);
        return zookeeperRegistryCenter;
    }
    /**
     *设置执行周期
     */
    @Bean
    public LiteJobConfiguration liteJobConfiguration(){

        JobCoreConfiguration jobCoreConfiguration= JobCoreConfiguration.newBuilder(MyJob.class.getName(),corn,shardingTotalCount).shardingItemParameters(shardingparamters).build();
        LiteJobConfiguration liteJobConfiguration = LiteJobConfiguration.newBuilder(new SimpleJobConfiguration(jobCoreConfiguration,MyJob.class.getName())).overwrite(true).build();
        return liteJobConfiguration;
    }
    /**
     * 执行任务调度
     */
    @Bean(initMethod = "init")
    public SpringJobScheduler springJobScheduler(MyJob job,ZookeeperRegistryCenter zookeeperRegistryCenter,LiteJobConfiguration liteJobConfiguration){


        return new SpringJobScheduler(job,zookeeperRegistryCenter,liteJobConfiguration);


    }


}

执行任务

@Component
public class MyJob implements SimpleJob {

    /**
     * 任务具体要做的事情
     * @param shardingContext
     */

    private SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private SearchFeign searchFeign;
    //保存我们的阈值条件 key为apiName value为访问的平均时间
     private static Map<String,Integer> mapRule=new HashMap<>();
    @Autowired
     private ApplicationContext applicationContext;

     static {
         mapRule.put("oderget_02",30);
         mapRule.put("testservice01_03",30);
     }

    @Override
    public void execute(ShardingContext shardingContext) {
        System.err.println("开始执行任务");
        //因为时区问题 需要减少八个小时 才能和es里面的时间一致
        Instant now = Instant.now();
        //监听时间段10秒内所有的访问
        Date from= Date.from(now.plusSeconds(-3600*8-10));
        Date to=Date.from(now.plusSeconds(-3600*8));
//        System.out.println(simpleDateFormat.format(from));
//        System.out.println(simpleDateFormat.format(to));
        //得到保存了apiName 和平均时间的 map

        Map<String, Integer> map = searchFeign.getAvg(simpleDateFormat.format(from), simpleDateFormat.format(to));
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            //得到结果的key apiName
            String key = entry.getKey();
            //得到平均时间 和规则的阈值比较
            Integer valueReal = entry.getValue();
            Integer valueRule = mapRule.get(key);
            if (valueReal<valueRule){
                System.err.println("服务" + key + "没有超出阈值");
            }
            else {
                System.err.println("服务" + key + "超出阈值,阈值为" + valueRule + "  当前为:" + valueReal);
                EventBean eventBean=new EventBean();
                eventBean.setMsg("服务" + key + "超出阈值,阈值为" + valueRule + "  当前为:" + valueReal);
                eventBean.setEventType(EventType.OVERTIME);
                applicationContext.publishEvent(eventBean);
            }
        }
        //发送邮件
//        System.err.println("服务"  + "超出阈值,阈值为"  + "  当前为:" );
//        EventBean eventBean=new EventBean();
//        eventBean.setMsg("服务"  + "超出阈值,阈值为"  + "  当前为:" );
//        eventBean.setEventType(EventType.OVERTIME);
//        applicationContext.publishEvent(eventBean);

    }
}

事件监听 发送邮件报警

@Component
public class SendMailEventListener {
    @EventListener
    public void send(EventBean eventBean) throws GeneralSecurityException, MessagingException {

        switch (eventBean.getEventType()) {
            case OVERTIME:
                Properties properties = new Properties();
                properties.put("mail.host", "smtp.163.com");//设置我们的服务器地址
                properties.put("mail.transport.protocol", "smtp");//设置邮箱发送的协议
                properties.put("mail.smtp.auth", "true");//设置需要认证
                MailSSLSocketFactory sf = new MailSSLSocketFactory();//创建 ssl 连接的工厂对象
                sf.setTrustAllHosts(true);//信任所有主机
                properties.put("mail.smtp.ssl.enable", "true");//设置开启 ssl
                properties.put("mail.smtp.ssl.socketFactory", sf);//设置对应的工厂对象

                Session session = Session.getDefaultInstance(properties, new Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication("chenzetao88886@163.com", "NGCTKBVTVUTDMDUF"); //返回认证信息
                    }
                });//创建会话

                session.setDebug(true);//控制台会显示一些调试的日志
                Transport transport = session.getTransport();//类似于我们的 sql 中的 statement
                transport.connect("smtp.163.com", "chenzetao88886@163.com", "NGCTKBVTVUTDMDUF");//通过邮箱和提供的密码来进行登录
                Message message = new MimeMessage(session);//创建消息对象,也就是邮件内容对象

                message.setFrom(new InternetAddress("chenzetao88886@163.com"));//设置对方显示的来自于谁的邮件
                //设置收件人
                message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("852086428@qq.com")});//设置收件人
                message.setSubject("接口超时预警邮件");//标题
                message.setContent(eventBean.getMsg(), "text/html;charset=utf-8");//正文

                transport.sendMessage(message, message.getAllRecipients());//发送

                transport.close();
                break;





    }


}}

其他依赖

 <dependencies>
        <dependency>
            <groupId>com.spingcloud</groupId>
            <artifactId>travel-entity</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
       
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
       
	
<!--        实体类-->
        <dependency>
            <groupId>com.spingcloud</groupId>
            <artifactId>travel-entity</artifactId>
            <version>1.0-SNAPSHOT</version>
<!--            过滤掉掉 mybatis-plus 依赖,之前用的是mybatis-->
            <exclusions>
                <exclusion>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                    <groupId>com.baomidou</groupId>
                </exclusion>
            </exclusions>

  </dependencies>

依赖

 <!--pagehelper注意和mybatisplus的问题-->
       <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!--注册到eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
	 <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>	
        </dependency>
<!--        hystrix 断路器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
<!--        jwt 认证用于sign签名 -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>


        <!--es-->
       <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>6.5.4</version>
            <!--<exclusions>-->
                <!--<exclusion>-->
                    <!--<artifactId>elasticsearch</artifactId>-->
                    <!--<groupId>org.elasticsearch</groupId>-->
                <!--</exclusion>-->
            <!--</exclusions>-->
        </dependency>
		
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>6.5.4</version>
        </dependency>


		<!--eureka服务端 启动类@EnableEurekaServer注解-->
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

.gitignore的忽略文件配置

HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/

### VS Code ###
.vscode/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值