搭建spring cloud
一共有如下模块:eureka-server注册中心user-server用户登录服务portal访问用户服务提供登录接口server-gateway服务网关实现目标: 对外开放网关端口,用户通过网关请求portal登录portal请求user-server验证用户名密码,认证成功返回一个token,携带此token可以访问登录以外的接口,否则不允许访问登录以外的...
·
一共有如下模块:
- eureka-server 注册中心
- user-server 用户登录服务
- portal 访问用户服务提供登录接口
- server-gateway 服务网关
实现目标: 对外开放网关端口,用户通过网关请求portal登录portal请求user-server验证用户名密码,认证成功返回一个token,携带此token可以访问登录以外的接口,否则不允许访问登录以外的接口。
Eureka:
- pom:
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.alien</groupId>
<artifactId>eureka-server7001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server7001</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- yml配置文件:
server:
port: 7001
eureka:
instance:
hostname: localhost # 地址
client:
register-with-eureka: false # 是否向自己注册
fetch-registry: false # 是否获取注册服务信息
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #注册地址
- 启动类:
package com.aline.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer7001Application {
public static void main(String[] args) {
SpringApplication.run(EurekaServer7001Application.class, args);
}
}
user-server
- pom
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.aline</groupId>
<artifactId>user-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 服务监控、管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.aline</groupId>
<artifactId>common_api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- yml配置文件
server:
port: 8002
spring:
jackson:
date-format: yyyy-MM-dd hh:mm:ss
jpa:
show-sql: true # 打印SQL日志
hibernate:
ddl-auto: update
database-platform: org.hibernate.dialect.SQLServer2012Dialect # 方言
datasource:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://localhost:1433;DatabaseName=cloud
username: sa
password: 123456
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 5
maximum-pool-size: 15
auto-commit: true
idle-timeout: 30000
pool-name: DatebookHikariCP
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
application:
name: userserver #应用名称,微服务调用名称
mybatis:
mapper-locations: classpath:mapper/*.xml #mybatis配置文件
info: #info节点显示信息
app.name: userserver
company.name: aline
build.artifactId: $project.artifactId$
build.version: $project.version$
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
shutdown:
enabled: false
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: userserver
prefer-ip-address: true
login:
keepTime: 1800
- 启动类
package com.aline.userserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient // 注册自己到eureka
@EnableDiscoveryClient // 服务发现
public class UserServerApplication {
public static void main(String[] args) {
SpringApplication.run(UserServerApplication.class, args);
}
}
portal
- pom
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.aline</groupId>
<artifactId>portal8001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>portal8001</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.aline</groupId>
<artifactId>common_api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.13</version>
</dependency>
<!-- eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 熔断器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- 熔断器表盘 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!-- feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 服务监控、管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
- yml配置文件:
server:
port: 8001
spring:
jackson:
date-format: yyyy-MM-dd hh:mm:ss
application:
name: portal
redis:
database: 0
host: 127.0.0.1
port: 6379
password:
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
shutdown:
enabled: false
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: portal
prefer-ip-address: true
feign: # feign访问配置
hystrix:
enabled: false
client:
config:
default:
connectTimeout: 7000
readTimeout: 7000
hystrix: # 熔断表盘监控
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 8000
- 启动类:
package com.aline.portalserver;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableDiscoveryClient // 服务发现
@EnableHystrix // 断路器
@EnableFeignClients // feign
@EnableHystrixDashboard // 断路器表盘
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Portalserver8001Application {
public static void main(String[] args) {
SpringApplication.run(Portalserver8001Application.class, args);
}
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
- feign调用借口
package com.yihong.portalserver.feign;
import com.yihong.common.entity.User;
import com.yihong.common.util.AjaxJson;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
/**
* @ClassName UserFeign
* @Description
* @Author 孟志浩
* @Date 2019/3/18 15:29
**/
// name指定请求的哪个微服务
@FeignClient(name = "userserver")
public interface UserFeign {
/**
* @GetMapping 指定请求微服务下的api路径
*/
@GetMapping("/user/list")
List<User> listUsers();
@PostMapping("/user/login")
AjaxJson login(User user);
}
- userFeignFallBack熔断配置(简单处理)
package com.yihong.portalserver.feignfallback;
import com.yihong.common.entity.User;
import com.yihong.common.util.AjaxJson;
import com.yihong.common.util.AjaxJsonFactory;
import com.yihong.portalserver.feign.UserFeign;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName UserFallBack
* @Description
* @Author 孟志浩
* @Date 2019/3/18 16:20
**/
@Component
public class UserFallBack implements UserFeign {
/**
*
* 调用失败返回信息
* @return com.yihong.portalserver.feign.UserFeign
* @author 孟志浩
* @date 2019/3/18
**/
@Override
public List<User> listUsers() {
User u = new User();
u.setLoginName("failed to call server [user server]");
List l = new ArrayList();
l.add(u);
return l;
}
@Override
public AjaxJson login(User user) {
return AjaxJsonFactory.createAjaxJson(400, "登录失败,暂停服务");
}
}
- feign头转发配置
package com.yihong.portalserver.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
/**
* @ClassName SecuringRequestInterceptor
* @Description 微服务之间调用需要加入该配置类,使用feign发送请求时携带本次请求的头信息
* @Author 孟志浩
* @Date 2019/3/19 16:39
**/
@Component
public class SecuringRequestInterceptor implements RequestInterceptor {
/**
* 使用feign发送请求时携带本次请求的头信息。
* 比如登录信息的传递,需要获取头中的Authorization解析token即可获取用户id
* @param requestTemplate
* @return void
* @author 孟志浩
* @date 2019/3/19
**/
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
requestTemplate.header(name, values);
}
}
}
}
网关geteway
- pom
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yihong</groupId>
<artifactId>server_getewat</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server_getewat</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.yihong</groupId>
<artifactId>common_api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
- yml 配置文件
server:
port: 8080
spring:
application:
name: servergeteway
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
prefer-ip-address: true
zuul:
routes:
userserver:
path: /userserver/**
serviceId: userserver
portal:
path: /portal/**
serviceId: portal
host:
connect-timeout-millis: 10000
socket-timeout-millis: 10000
sensitive-headers:
login:
keepTime: 1800
- 启动类
package com.yihong.zuulserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class ZuulServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServerApplication.class, args);
}
}
- 网关过滤
package com.yihong.zuulserver.filter;
import com.alibaba.fastjson.JSON;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.yihong.common.util.AjaxJson;
import com.yihong.common.util.AjaxJsonFactory;
import com.yihong.common.util.JwtUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* @ClassName SecurityFilter
* @Description 登录拦截
* 拦截器,如果return null 正常访问各个微服务的接口
* 如果被拦截器拦截将会返回处理的信息,也将不会访问日志记录
* @Author 孟志浩
* @Date 2019/3/19 15:31
**/
@Component
public class SecurityFilter extends ZuulFilter {
@Autowired
private RedisTemplate redisTemplate;
@Value("${login.keepTime}")
private Long keepTime;
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException{
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
HttpServletResponse response = ctx.getResponse();
String url = request.getRequestURL().toString();
if (!url.contains("/login")) {
AjaxJson resJson = AjaxJsonFactory.createAjaxJson(405, "请登录后访问");
// 获取请求的tokenKey
String tokenKey = request.getHeader("Authorization");
// 没有携带tokenKey
if (StringUtils.isBlank(tokenKey)) {
ctx.setResponseBody(JSON.toJSONString(resJson));
return false;
}
// 判断tokenKey是否在Redis中过期
if (!redisTemplate.hasKey(tokenKey)) {
ctx.setResponseBody(JSON.toJSONString(resJson));
return false;
} else {
redisTemplate.opsForValue().set(tokenKey, "p", keepTime, TimeUnit.SECONDS);
}
}
return null;
}
}
更多推荐
已为社区贡献2条内容
所有评论(0)