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.gradlegroup 'org.sauceggplant'version '0.0.1-SNAPSHOT'apply plugin: 'java'apply plugin: 'spring-boot'sourceCompatibility = 1.8targetCompatibility = 1.8repositories { 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.javapackage org.sauceggplant.qrcode;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication@EnableEurekaClientpublic 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.javapackage 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; Maphints = new HashMap (); 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 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 hints = new HashMap (); 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 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 hints = new HashMap (); 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.javapackage 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@EnableSwagger2public 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.ymlserver: port: 8762spring: application: name: QRCode# cloud:# config:# server:# git:# url: http://192.168.56.101/zhaozx/config-repo/qrcode# profiles:# active: deveureka: client: serviceUrl: defaultZone: http://127.0.0.1:8761/eureka/ #Eureka服务注册成地址
bootstrap.yml
#bootstrap.ymleureka: instance: lease-renewal-interval-in-seconds: 10 # 心跳时间,即服务续约间隔时间(缺省为30s) lease-expiration-duration-in-seconds: 60 # 发呆时间,即服务续约到期时间(缺省为90s) client: healthcheck: enabled: true