模块结构
image.png.................................................................................................
模块代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud</artifactId>
<groupId>com.yyd.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>data-provide-client-8005</artifactId>
<dependencies>
<!--springcloud-config依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- SpringCloud Eureka 注册中心依赖 客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- actutor完善监控信息(erekua的status指向网页的信息依赖)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- spirngboot测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<!-- springboot的web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- web服务 替代tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!-- Hystrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<!--指定打包方式 loader.path使用-->
<layout>ZIP</layout>
<!--去除在生产环境中不变的依赖,只包含业务代码-->
<includes>
<include>
<groupId>com.yyd.cloud</groupId>
<artifactId>*</artifactId>
</include>
</includes>
</configuration>
</plugin>
<!--拷贝依赖jar到lib-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<!--拷贝资源文件 copy-resources, config固定 -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<outputDirectory>${project.build.directory}/config</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!--拷贝target下的jar到targets-->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>copy-lib-target</id>
<phase>package</phase>
<configuration>
<tasks>
<copy todir="../targets">
<fileset dir="target">
<include name="*.jar"/>
</fileset>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<!-- 排除资源文件 -->
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.yml</exclude>
</excludes>
</resource>
</resources>
</build>
</project>
.................................................................................................
DockerFile
# 基础 JRE 镜像
FROM registry.cn-hangzhou.aliyuncs.com/ydyan/cloud:v0.1
MAINTAINER 13270809619@163.com
WORKDIR /root/data-provide-client-8005
ENV APP_HOME=/root/data-provide-client-8005
ENV MAIN_JAR=data-provide-client-8005-1.0-SNAPSHOT.jar
ENV JVMOPTIONS="-Xms128M -Xmx1G"
#声明容器端口
ENV EXPOSE_PORT=8005
ENV CONFIG_LABEL=master
ENV ENV_TYPE=dev
# 修改时区,使得容器时间为北京时间
RUN echo "Asia/Shanghai" > /etc/timezone
# 将所需项目文件复制进入容器中
ADD target/$MAIN_JAR $APP_HOME/
ADD target/lib/ $APP_HOME/lib/
ADD target/config/ $APP_HOME/config/
# 运行项目
CMD java $JVMOPTIONS -jar -Dloader.path=$APP_HOME,$APP_HOME/lib -Dfile.encoding=UTF-8 $APP_HOME/$MAIN_JAR
EXPOSE $EXPOSE_PORT
#---docker服务---
#docker pull centos:7
#docker tag 37bb9c63c8b2 registry-vpc.cn-hangzhou.aliyuncs.com/acs/agent:0.7-dfb6816 镜像改名
#docker build -t yd-cloud:v0.1 .
#docker run -d -p 9001:9001 -p 9002:9002 yd-cloud:v0.1
#docker run -d -p 10001:8888(本机:容器) -name springboot(容器名称) -v /usr/local/bigdata/dockerlogs/:/usr/local/logs/ yd-cloud:v0.1
#docker ps -a (全部容器) |docker ps (运行中容器)
#docker exec -it 8b /bin/bash (进入容器)
#docker logs -f -t --tail 500 容器名称/容器id 查看docker日志
#docker images 查看镜像
#docker kill 容器名称/容器id
#docker rm 容器名称/容器id
#docker rmi 镜像id
#docker image rm -f 镜像id
.................................................................................................
resources
application-prod.yml
prod.name: prodname
.................................................................................................
bootstrap.yml
server:
port: 8005
# http://localhost:9001/personnel/refresh
# webhooks 提交推送
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: "*"
base-path: /
#spring配置
spring:
application:
name: data-provide
cloud:
config:
label: master
profile: dev
name: service-config
discovery:
enabled: true
service-id: service-config
profiles:
active: prod
#Eureka的配置,服务注册到哪里
eureka:
client:
service-url:
#做集群需要关联集群的eureka服务器的地址,其实端口号都应该是7001,
#关联的只是服务器地址,这里因为只有一台电脑,就用了端口号代替
#集群模式 defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/,http://127.0.0.1:7003/eureka/
#单机模式 defaultZone: http://127.0.0.1:7001/eureka/
defaultZone: http://127.0.0.1:7001/eureka/
# 此应用为注册中心,false:不向注册中心注册自己
register-with-eureka: true
# 注册中心职责是维护服务实例,false:不检索服务
fetch-registry: true
instance:
instance-id: data-provide-client #实例化id 集群id
#info配置
info:
app.name: data-provide
company.name: com.yyd
.................................................................................................
logback.xml
<configuration scanPeriod="10 seconds" debug="true">
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} [%file : %line] - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily 配置日志所生成的目录以及生成文件名的规则 -->
<fileNamePattern>logs/data-provide-8005-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- 单个日志文件最大100MB -->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 日志文件保存15天 -->
<maxHistory>15</maxHistory>
</rollingPolicy>
<prudent>false</prudent>
</appender>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- Console 输出设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!--<springProfile name="dev,test,prod">-->
<!--<root level="INFO">-->
<!--<appender-ref ref="CONSOLE"/>-->
<!--<appender-ref ref="FILE"/>-->
<!--</root>-->
<!--<!–<logger name="com.yyd.mapper" level="DEBUG"/>–>-->
<!--</springProfile>-->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
java
ConfigBean.java
package com.yyd.dataprovide.config;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/***
* @ClassName: ConfigBean
* @Description: TODO
* @author: yanyd
* @Date: 7:54 2020/5/31
* @version : V1.0
*/
@Slf4j
@Configuration
public class ConfigBean {
/**
* 增加一个servlet,将8001服务注册到dashboard流监控
* @return
*/
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
registrationBean.addUrlMappings("/actuator/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
RequestController.java
package com.yyd.dataprovide.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.yyd.dataprovide.service.RequestService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/***
* @ClassName: RequestController
* @Description: TODO
* @author: yanyd
* @Date: 1:51 2020/5/31
* @version : V1.0
*/
@RefreshScope
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/request")
public class RequestController {
private final RequestService requestService;
@Value("${web-site.url}")
private String url;
@Value("${prod.name}")
private String prodName;
@GetMapping(value = "/config")
public String config() {
return url+" "+prodName;
}
@HystrixCommand(fallbackMethod = "requestPostHystrix")//使用监控必须添加 HystrixCommand
@PostMapping(value = "/data", produces = {"application/json;charset=utf-8"})
public Map requestPost(@RequestBody Map map) {
int i = 1 / 0;
return requestService.requestPost(map);
}
@HystrixCommand(fallbackMethod = "requestGetHystrix")//使用监控必须添加 HystrixCommand
@GetMapping(value = "/data/{param}")
public Map requestGet(@PathVariable("param") String param) {
int i = 1 / 0;
return requestService.requestGet(param);
}
@HystrixCommand(fallbackMethod = "requestGetHystrix")//使用监控必须添加 HystrixCommand
@GetMapping(value = "/data/v1/{param}")
public Map requestGet1(@PathVariable("param") String param) {
int i = 1 / 0;
return requestService.requestGet(param);
}
//服务熔断(对get方法做熔断处理)
public Map requestGetHystrix(@PathVariable("param") String param, Throwable throwable) {
throwable.printStackTrace();
HashMap<String, Object> map = new HashMap<>();
map.put("param", param);
map.put("hystrix", "get request hystrix");
return map;
}
//服务熔断(对post方法做熔断处理)
public Map requestPostHystrix(@RequestBody Map map, Throwable throwable) {
throwable.printStackTrace();
map.put("hystrix", "pos request hystrix");
return map;
}
}
RequestServiceImpl.java
package com.yyd.dataprovide.service.impl;
import com.yyd.dataprovide.service.RequestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/***
* @ClassName: RequestServiceImpl
* @Description: TODO
* @author: yanyd
* @Date: 1:55 2020/5/31
* @version : V1.0
*/
@Service
@Slf4j
public class RequestServiceImpl implements RequestService {
@Override
public Map requestPost(Map map) {
map.put("msg", "post request success (*╹▽╹*)!");
map.put("req","8004");
return map;
}
@Override
public Map requestGet(String param) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("msg", "get request success (*╹▽╹*)!");
map.put("param",param);
map.put("req","8004");
return map;
}
}
RequestService.java
package com.yyd.dataprovide.service;
import java.util.Map;
/***
* @ClassName: RequestService
* @Description: TODO
* @author: yanyd
* @Date: 1:55 2020/5/31
* @version : V1.0
*/
public interface RequestService {
/**
* post
* @param map
* @return
*/
Map requestPost(Map map);
/**
* post
* @param
* @return
*/
Map requestGet(String param);
}
DataProvideApplication.java
package com.yyd.dataprovide;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/***
* @ClassName: DataProvideApplication
* @Description: TODO
* @author: yanyd
* @Date: 0:48 2020/5/31
* @version : V1.0
*/
@EnableCircuitBreaker //添加对熔断的支持
@EnableEurekaClient //在服务启动之后自动注册到eureka中
@EnableDiscoveryClient //服务发现
@SpringBootApplication
public class DataProvideApplication {
public static void main(String[] args) {
SpringApplication.run(DataProvideApplication.class, args);
}
}
网友评论