spring boot实现微服务负载均衡,https实现对外访问接口,试用于安全性要求高的并发系统
需求: 传统web程序实现负载均衡基本都是通过web容器或者防火墙设备,比如:nginx、apache的负载均衡,防火墙负载均衡,再加上tomcat或者其他容器的集群。 那么有没有通过代码方式实现负载均衡的方式呢?实现: spring boot为我们提供了一直实现方式。主要通过均衡管理服务器(server)+功能实现服务器(client)+对...
需求:
传统web程序实现负载均衡基本都是通过web容器或者防火墙设备,比如:nginx、apache的负载均衡,防火墙负载均衡,再加上tomcat或者其他容器的集群。
那么有没有通过代码方式实现负载均衡的方式呢?
实现:
spring boot为我们提供了一直实现方式。主要通过均衡管理服务器(server)+功能实现服务器(client)+对外服务服务器(consumer)。
开发软件:
Intellij IDEA 14.1.4
实现详细:
一、负载均衡服务器(server)
1、新建项目,所属框架勾选Cloud Discovery下Eureka Server
项目启动类:
package com.my.balanceserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class BalanceServerApplication { public static void main(String[] args) { SpringApplication.run(BalanceServerApplication.class, args); } }
可以看到,很简洁,只需要另外加注解:@EnableEurekaServer
2、项目配置文件
application.properties
server.port=8080 eureka.instance.hostname=127.0.0.1 eureka.client.registerWithEureka=false eureka.client.fetchRegistry=false eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
需要注意的是服务不需要注册自己
二、实际提供功能服务器(client)
该服务器是系统所有业务操作的所在,所有和数据库相关的操作都在这里执行。
1、新建项目,所属框架勾选Cloud Discovery下Eureka Server
项目启动类:
@SpringBootApplication @EnableEurekaClient public class BalanceClientApplication { public static void main(String[] args) { SpringApplication.run(BalanceClientApplication.class, args); } }
可以看到,也很简洁,只需要另外加注解:@EnableEurekaClient
2、项目配置文件
application.properties
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8080/eureka/ server.port=8088 spring.application.name=service-provider
需要填写负载均衡服务器地址和端口号,以及该服务的地址
三、对外提供接口项目(consumer)
consumer是对外提供接口,这里就涉及到安全问题,可以采取https方式,在银行系统等安全性比较高的项目中会应用到,也可以使用http+token令牌方式。
这里我们采取https方式
1、先生成秘钥文件:tomcat.key
在jdk bin下运行下面命令
keytool -genkeypair -alias tomcat -keyalg RSA -keystore D:/tomcat.key
然后按照操作输入对应相关信息即可,我这边密码设置为一样的。
2、新建项目,所属框架勾选spring web 和 Cloud Discovery下Eureka Server
项目启动类:
@SpringBootApplication @EnableEurekaClient public class BalanceConsumerApplication { @Value("${tomcat.port}") private Integer tomcatPort; @Value("${https.port}") private Integer port; @Value("${https.ssl.key-password}") private String keyStorePassword; @Value("${https.ssl.key-password}") private String keyPassword; @Value("${https.ssl.key-type}") private String keyType; public static void main(String[] args) { SpringApplication.run(BalanceConsumerApplication.class, args); } @Bean public ServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); tomcat.addAdditionalTomcatConnectors(createSslConnector()); return tomcat; } private Connector createSslConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); try { File keystore = new ClassPathResource("tomcat.key").getFile(); /*File truststore = new ClassPathResource("sample.jks").getFile();*/ connector.setScheme("https"); connector.setSecure(true); connector.setPort(port); protocol.setSSLEnabled(true); protocol.setKeystoreType(keyType); protocol.setKeystoreFile(keystore.getAbsolutePath()); protocol.setKeystorePass(keyStorePassword); protocol.setKeyPass(keyStorePassword); return connector; } catch (IOException ex) { throw new IllegalStateException("can't access keystore: [" + "keystore" + "] or truststore: [" + "keystore" + "]", ex); } } @Bean public Connector httpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(tomcatPort); connector.setSecure(false); connector.setRedirectPort(port); return connector; } }
这里把端口从配置文件中读取:
3、编写http过滤类,把http请求转换成https请求
@Configuration @WebFilter public class SslFilter extends OncePerRequestFilter { @Value("${tomcat.port}") private Integer tomcatPort; @Value("${https.port}") private Integer port; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestURL = request.getRequestURL().toString(); String protocol = requestURL.split("://")[0]; if ("http".equals(protocol)) { requestURL = requestURL.replace("http", "https").replace(Integer.toString(tomcatPort), Integer.toString(port)); response.sendRedirect(requestURL); } filterChain.doFilter(request, response); } }
4、配置文件
application.properties
server.port=88 tomcat.port=88 https.port=89 https.ssl.key-store=classpath:tomcat.key https.ssl.key-type=JKS https.ssl.key-password=nankang123456 eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8080/eureka/ spring.application.name=service-consumer
5、编写reset对外暴露的接口类
这里只写了一个测试接口:
@RestController public class ResetController { @Autowired RestTemplate restTemplate; /** * 实例化RestTemplate * @return */ @LoadBalanced @Bean public RestTemplate rest() { return new RestTemplate(); } @RequestMapping(value = "/api/{ope}/{params}",method = RequestMethod.POST) @ResponseBody public Result api(@PathVariable int ope,@PathVariable String params){ Result result=new Result(); String data = (String)restTemplate.getForObject("http://service-provider/api/"+ope+"/"+params,String.class); result.setData(data); return result; } }
另外还可以写一个http junit的测试类,用httpclient测试接口,这个请看下回分解。
代码github地址
顺便给大家推荐给开源客服系统,小倍客服。
更多推荐
所有评论(0)