Spring Boot调用Google Vision OCR API超时无响应求助
Hey there, let's work through this DEADLINE_EXCEEDED issue you're hitting when calling Google Vision's OCR API. The error typically pops up because your request is taking longer than the default timeout window, or there's a network/configuration block slowing things down. Here are the most effective fixes to try:
1. Increase the Request Timeout
The default gRPC timeout for Vision API requests is quite short (usually around 10 seconds). For larger images or slower networks, this isn't enough. You can explicitly set a longer timeout when building your ImageAnnotatorSettings:
import com.google.api.gax.retrying.RetrySettings; import java.time.Duration; // ... existing credential setup code ... ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder() .setCredentialsProvider(FixedCredentialsProvider.create(credentials)) // Set a custom total timeout (adjust to 30-60 seconds based on your needs) .setBatchAnnotateImagesSettings( BatchAnnotateImagesSettings.newBuilder() .setRetrySettings( RetrySettings.newBuilder() .setTotalTimeout(Duration.ofSeconds(30)) .build() ) .build() ) .build();
This gives the API more time to process your image before triggering a timeout.
2. Check Network & Proxy Configuration
If you're on a corporate network or behind a proxy, gRPC (which uses HTTP/2) might be getting blocked. Here's how to handle proxies:
Option A: JVM Proxy Arguments
Add these to your Maven run configuration or JVM startup parameters:
-Dhttp.proxyHost=your-proxy-host -Dhttp.proxyPort=your-proxy-port -Dhttps.proxyHost=your-proxy-host -Dhttps.proxyPort=your-proxy-port
Option B: Code-Based Proxy Setup
Configure the proxy directly in your ImageAnnotatorSettings:
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; import com.google.api.gax.rpc.ProxySettings; // ... existing credential setup code ... // Configure proxy details ProxySettings proxySettings = ProxySettings.newBuilder() .setHost("your-proxy-host") .setPort(8080) // Replace with your actual proxy port .build(); InstantiatingGrpcChannelProvider channelProvider = InstantiatingGrpcChannelProvider.newBuilder() .setProxySettings(proxySettings) .build(); ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder() .setCredentialsProvider(FixedCredentialsProvider.create(credentials)) .setTransportChannelProvider(channelProvider) // Don't forget to add the timeout setting from fix #1 too .setBatchAnnotateImagesSettings( BatchAnnotateImagesSettings.newBuilder() .setRetrySettings( RetrySettings.newBuilder() .setTotalTimeout(Duration.ofSeconds(30)) .build() ) .build() ) .build();
3. Optimize Image Size
Large high-resolution images take longer to transfer and process. Compress your image before sending it to the API to cut down on processing time:
import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.stream.ImageOutputStream; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Iterator; // Helper method to compress images public static byte[] compressImage(String imagePath, float quality) throws IOException { File inputFile = new File(imagePath); BufferedImage image = ImageIO.read(inputFile); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg"); if (!writers.hasNext()) throw new IOException("No JPG writer found"); ImageWriter writer = writers.next(); ImageWriteParam param = writer.getDefaultWriteParam(); param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionQuality(quality); // 0.0 = lowest quality, 1.0 = original writer.setOutput(ImageIO.createImageOutputStream(outputStream)); writer.write(null, new javax.imageio.IIOImage(image, null, null), param); writer.dispose(); return outputStream.toByteArray(); }
Then use this in your main code instead of reading the raw file:
// Replace Files.readAllBytes(path) with: byte[] data = compressImage(fileName, 0.5f); // Adjust quality as needed ByteString imgBytes = ByteString.copyFrom(data);
4. Verify Permissions & Service Health
- Double-check that your service account has the Cloud Vision API User (
roles/vision.user) role assigned in Google Cloud Console. Missing permissions can sometimes manifest as unexpected timeouts. - Confirm the Google Vision API is operational by checking the Google Cloud Service Health Dashboard (you can find this directly in the Google Cloud Console).
内容的提问来源于stack exchange,提问作者user4507518

