Eureka的服务注册和服务发现是一起的,服务发现是一个服务,将自己暴露给Eureka的服务注册,这样别人就可以通过Eureka调用服务了。Eureka服务注册本身是也个服务,也可以配置集群。
Eureka的服务注册会在集群中同步服务发现的数据,保证服务高可用。通过Feign,Ribbon等方式可以调用服务注册暴露的服务,Feign和Ribbon都是客户端的LB(负载均衡),实际使用中,可加一层网关Zuul,Zuul网关也可以做集群,在网关之上可以配置服务端的LB。
这里做一个二维码的微服务,来说明Eureka服务发现。
Eureka服务发现,需要引入spring-cloud-starter-eureka
springfox-swagger2是一套在线Rest API文档
zxing是用于二维码的生成和解析的
//build.gradle
group 'org.sauceggplant'
version '0.0.1-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'spring-boot'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
maven{url 'http://192.168.56.103:8081/repository/zhaozx/'}
}
dependencies {
compile 'org.springframework.cloud:spring-cloud-starter-config:1.3.1.RELEASE'
compile 'org.springframework.cloud:spring-cloud-starter-eureka:1.3.1.RELEASE'
compile 'org.springframework.boot:spring-boot-actuator:1.5.3.RELEASE'
compile 'io.springfox:springfox-swagger2:2.7.0'
compile 'io.springfox:springfox-swagger-ui:2.7.0'
compile 'com.google.zxing:core:3.3.0'
compile 'com.google.zxing:javase:3.3.0'
testCompile 'org.springframework.boot:spring-boot-starter-test:1.5.3.RELEASE'
}
buildscript {
repositories {
maven{url 'http://192.168.56.103:8081/repository/zhaozx/'}
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.3.RELEASE'
}
}
jar {
baseName = 'QRCode'
version = '0.0.1-SNAPSHOT'
}
启动类中配置@EnableEurekaClient启动Eureka的服务发现
//QRCodeApplication.java
package org.sauceggplant.qrcode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class QRCodeApplication {
public static void main(String[] args) {
SpringApplication.run(QRCodeApplication.class,args);
}
}
二维码服务的Controller,与SpringMVC的Controller没什么区别。
@RestController声明一个restful风格的Controller
@RequestMapping表示请求的路径
@ApiOperation是swagger2的注解,加上注解后可以生成在线swagger文档
@RequestParam是请求的参数(@RequestBody请求体)
@ResponseBody是返回的内容
//QRCodeController.java
package org.sauceggplant.qrcode.controller;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.HybridBinarizer;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/qrcode")
public class QRCodeController {
private static BASE64Decoder decoder = new BASE64Decoder();
private static BASE64Encoder encoder = new BASE64Encoder();
@ApiOperation(value = "获取二维码图片",notes = "获取二维码图片",produces="image/*")
@RequestMapping(value = "/image", method = RequestMethod.GET, produces="image/*")
public void getQRCode(HttpServletResponse response, @RequestParam int width,@RequestParam int height,@RequestParam String format,@RequestParam String content) {
try {
width=width==0?200:width;
height=height==0?200:height;
format=format==null?"png":format;
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(content==null?"NULL":content,BarcodeFormat.QR_CODE, width, height, hints);
OutputStream outputStream = (OutputStream)response.getOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix,format,outputStream);
if(outputStream!=null){
outputStream.close();
}
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@ApiOperation(value = "获取二维码信息",notes = "获取二维码信息")
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> getQRCodeString(@RequestParam int width,@RequestParam int height,@RequestParam String format,@RequestParam String content) {
try {
width=width==0?200:width;
height=height==0?200:height;
format=format==null?"png":format;
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(content==null?"NULL":content,BarcodeFormat.QR_CODE, width, height, hints);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix,format,byteArrayOutputStream);
String data = encoder.encode(byteArrayOutputStream.toByteArray());
return new ResponseEntity(data,HttpStatus.OK);
} catch (WriterException e) {
e.printStackTrace();
return new ResponseEntity(null, HttpStatus.INTERNAL_SERVER_ERROR);
} catch (IOException e) {
e.printStackTrace();
return new ResponseEntity(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@ApiOperation(value = "获取二维码信息",notes = "获取二维码信息")
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<String> postQRCode(@RequestBody(required = true) String content) {
try {
byte[] data = decoder.decodeBuffer(content);
BufferedImage image;
ByteArrayInputStream in = new ByteArrayInputStream(data);
image = ImageIO.read(in);
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
Result result = new MultiFormatReader().decode(binaryBitmap, hints);
return new ResponseEntity(result.getText(), HttpStatus.OK);
} catch (IOException e) {
e.printStackTrace();
return new ResponseEntity(null, HttpStatus.INTERNAL_SERVER_ERROR);
} catch (NotFoundException e) {
e.printStackTrace();
return new ResponseEntity(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Swagger2配置
//SwaggerConfiguration.java
package org.sauceggplant.qrcode.swagger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("二维码微服务")
.description("二维码生成,解析")
.version("0.0.1-SNAPSHOT")
.build())
.select()
.apis(RequestHandlerSelectors.basePackage("org.sauceggplant.qrcode.controller"))
.paths(PathSelectors.any())
.build();
}
}
application.yml
#application.yml
server:
port: 8762
spring:
application:
name: QRCode
# cloud:
# config:
# server:
# git:
# url: http://192.168.56.101/zhaozx/config-repo/qrcode
# profiles:
# active: dev
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/ #Eureka服务注册成地址
bootstrap.yml
#bootstrap.yml
eureka:
instance:
lease-renewal-interval-in-seconds: 10 # 心跳时间,即服务续约间隔时间(缺省为30s)
lease-expiration-duration-in-seconds: 60 # 发呆时间,即服务续约到期时间(缺省为90s)
client:
healthcheck:
enabled: true
http://127.0.0.1:8762/swagger...