9

मैं एक सेटअप बहुत ज्यादा एक छवि यहाँ में विस्तृत की तरह है कि के साथ प्रयोग कर रहा हूँ: https://raw.githubusercontent.com/Oreste-Luci/netflix-oss-example/master/netflix-oss-example.pngपीडब्ल्यूएस पर वसंत बादल/नेटफ्लिक्स ढेर के साथ नीले/हरे रंग की तैनाती करने का कैननिक तरीका क्या है?

enter image description here

मेरी सेटअप में, मैं एक क्लाइंट अनुप्रयोग (https://www.joedog.org/siege-home/), एक प्रॉक्सी (उपयोग कर रहा हूँ जुउल), एक खोज सेवा (यूरेका) और एक साधारण माइक्रोस्कोप। सब कुछ पीडब्ल्यूएस पर तैनात किया गया है।

मैं अपने सरल माइक्रोस्कोस के एक संस्करण से अगले पर बिना डाउनटाइम के माइग्रेट करना चाहता हूं। शुरुआत में मैंने यहां वर्णित तकनीक के साथ शुरुआत की: https://docs.cloudfoundry.org/devguide/deploy-apps/blue-green.html

मेरी राय में, यह दृष्टिकोण यूरेका जैसी खोज सेवा के साथ "संगत" नहीं है। असल में, मेरी सेवा का नया संस्करण यूरेका में पंजीकृत है और मैं सभी मार्गों (सीएफ राउटर) को रीमेप करने से पहले यातायात प्राप्त करता हूं।

यह मैं एक और दृष्टिकोण, जिसमें मैं वसंत बादल/Netflix में विफलता तंत्र पर भरोसा करने के लिए नेतृत्व:

  1. मैं अपने सेवा की एक नई (पीछे की ओर संगत) संस्करण स्पिन।
  2. जब यह संस्करण जुउल/यूरेका द्वारा उठाया जाता है तो यह 50% यातायात प्राप्त करना शुरू कर देता है।
  3. एक बार जब मैंने सत्यापित किया कि नया संस्करण सही तरीके से काम करता है तो मैं "पुराना" उदाहरण लेता हूं।

मैं समझता हूँ के रूप में (मैं सिर्फ "रोक" PWS में बटन क्लिक करें), Zuul रिबन (लोड-संतुलन) का उपयोग करता हुड के नीचे है कि दूसरे विभाजन जहां पुराने उदाहरण यूरेका में अब भी है में तो है लेकिन वास्तव में नीचे बंद , मुझे उम्मीद है कि क्लाइंट पर किसी भी प्रभाव के बिना नए इंस्टेंस पर पुनः प्रयास करें।

हालांकि, मेरी धारणा गलत है।

Lifting the server siege...  done. 

Transactions:    5305 hits 
Availability:    99.96 % 
Elapsed time:    59.61 secs 
Data transferred:   26.06 MB 
Response time:    0.17 secs 
Transaction rate:   89.00 trans/sec 
Throughput:    0.44 MB/sec 
Concurrency:    14.96 
Successful transactions:  5305 
Failed transactions:    2 
Longest transaction:   3.17 
Shortest transaction:   0.14 

मेरी application.yml

server: 
    port: ${PORT:8765} 

info: 
    component: proxy 

ribbon: 
    MaxAutoRetries: 2 # Max number of retries on the same server (excluding the first try) 
    MaxAutoRetriesNextServer: 2 # Max number of next servers to retry (excluding the first server) 
    OkToRetryOnAllOperations: true # Whether all operations can be retried for this client 
    ServerListRefreshInterval: 2000 # Interval to refresh the server list from the source 
    ConnectTimeout: 3000 # Connect timeout used by Apache HttpClient 
    ReadTimeout: 3000 # Read timeout used by Apache HttpClient 

hystrix: 
    threadpool: 
     default: 
     coreSize: 50 
     maxQueueSize: 100 
     queueSizeRejectionThreshold: 50 
    command: 
    default: 
     execution: 
     isolation: 
      thread: 
      timeoutInMilliseconds: 10000 

का एक हिस्सा मुझे यकीन है कि क्या गलत हो जाता है नहीं कर रहा हूँ: मैं अपने ग्राहक में कुछ 502 त्रुटियों मिलता है।

क्या यह एक तकनीकी मुद्दा है?

या क्या मैं गलत धारणाएं कर रहा हूं (मैंने कहीं पढ़ा है कि POSTs को फिर से नहीं बदला गया है, जिसे मैं वास्तव में समझ नहीं पा रहा हूं)?

मुझे यह सुनना अच्छा लगेगा कि आप इसे कैसे करते हैं।

धन्यवाद, एंडी

उत्तर

2

मैंने इसके बारे में भी सोचा है। मैं स्प्रिंग क्लाउड "क्रोध में" इस्तेमाल करने का दावा नहीं करूंगा। मैं बस थोड़ी देर के लिए इसका प्रयोग कर रहा हूं।

धारणा: हम मानते हैं कि सभी उदाहरण राज्यों के लिए सच्चाई का स्रोत यूरेका में संग्रहीत है, तो यूरेका परिचालन नियंत्रण का हमारा तंत्र होना चाहिए। हम यूरेका का उपयोग उदाहरण स्थिति को OUT_OF_SERVICE पर सेट करके सेवा से बाहर निकलने के लिए कर सकते हैं। जब रिबन अपनी सर्वर सूची को रीफ्रेश करता है तो यह इन्हें सेवा उदाहरणों से बाहर नहीं करेगा। यूरेका उदाहरण पूछताछ और इंस्टेंस स्थिति सेट करने के लिए एक आरईएसटी एपीआई प्रदान करता है। महान।

समस्या है: मुझे कैसे पता चलेगा जो उदाहरणों ब्लू समूह में हैं और जो उदाहरणों ग्रीन समूह में हैं?

मैं सोच रहा था ... यूरेका प्रत्येक उदाहरण के लिए एक मेटाडाटा नक्शा प्रदान करता है। हमारे निर्माण/सेंकने के चरण में कहें कि हमने मेटाडेटा मानचित्र में एक संस्करण आईडी सेट की है? हम एक गिट प्रतिबद्ध आईडी या कुछ अर्थपूर्ण संस्करण योजना या जो कुछ भी उपयोग कर सकते हैं। ठीक है, अब मैं यूरेका मेटाडेटा देख सकता हूं और ब्लू बनाम ग्रीन इंस्टेंस को उस संस्करण मान के रूप में देख सकता हूं। हम गुणों का उपयोग कर प्रत्येक सेवा में मेटाडेटा मान सेट कर सकते हैं।

उदा eureka.instance.metadataMap.version=8675309

अब अगर हम सिर्फ यूरेका बता सकते हैं क्या अच्छा होगा है। "सेवा के बाहर FUBAR सेवा और संस्करण 867530 9 के लिए सभी उदाहरण लें।" खैर, मुझे नहीं लगता कि बॉक्स से बाहर प्रदान किया गया है। स्प्रिंग क्लाउड के बारे में अच्छी बात ये है कि यूरेका सर्वर समेत ये सभी सेवाएं केवल स्प्रिंग ऐप्स हैं जिन्हें हम अपनी जरूरतों के लिए हैक कर सकते हैं। नीचे दिया गया कोड एक अंत बिंदु का खुलासा करता है जो ऐप नाम और एक संस्करण दिए गए "सेवा से बाहर" उदाहरणों को सेट करता है। बस इस कंट्रोलर को अपने यूरेका सर्वर में जोड़ें। यह उत्पादन तैयार नहीं है, वास्तव में सिर्फ एक विचार है।

अब एक बार यूरेका सेवा से बाहर इन उदाहरणों लेता है और रिबन अपने सर्वर सूची ताज़ा करता है यह मारने या इन उदाहरणों से मार्ग दूर करने के लिए सुरक्षित है।

http://[eurekahost:port]/takeInstancesOutOfService?applicationName=FOOBAR&version=8675309 

आशा है कि मदद करता है:

को पोस्ट?

import java.util.Collection; 
import java.util.function.Predicate; 
import java.util.stream.Collectors; 

import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.RestController; 

import com.netflix.appinfo.InstanceInfo; 
import com.netflix.appinfo.InstanceInfo.InstanceStatus; 
import com.netflix.discovery.shared.Application; 
import com.netflix.eureka.EurekaServerContextHolder; 
import com.netflix.eureka.registry.PeerAwareInstanceRegistry; 

@RestController 
public class EurekaInstanceStateController { 

    @RequestMapping(value="/instancesQuery", method=RequestMethod.POST) 
    public Collection<String> queryInstancesByMetaData(
      @RequestParam("applicationName") String applicationNameCriteria, 
      @RequestParam("version") String versionCriteria) 
    { 
     return getRegistry().getSortedApplications() 
       .stream() 
       .filter(hasApplication(applicationNameCriteria)) 
       .flatMap(app -> app.getInstances().stream()) 
       .filter(hasVersion(versionCriteria)) 
       .map(info -> info.getAppName() + " - " + info.getId() + " - " + info.getStatus() + " - " + info.getMetadata().get("version")) 
       .collect(Collectors.toList()); 
    } 

    @RequestMapping(value="/takeInstancesOutOfService", method=RequestMethod.POST) 
    public Collection<String> takeInstancesOutOfService(
      @RequestParam("applicationName") String applicationNameCriteria, 
      @RequestParam("version") String versionCriteria) 
    { 
     return getRegistry().getSortedApplications() 
       .stream() 
       .filter(hasApplication(applicationNameCriteria)) 
       .flatMap(app -> app.getInstances().stream()) 
       .filter(hasVersion(versionCriteria)) 
       .map(instance -> updateInstanceStatus(instance, InstanceStatus.OUT_OF_SERVICE)) 
       .collect(Collectors.toList()); 
    } 

    /** 
    * @param instance 
    * @return 
    */ 
    private String updateInstanceStatus(InstanceInfo instance, InstanceStatus status) 
    { 
     boolean isSuccess = getRegistry().statusUpdate(instance.getAppName(), instance.getId(), 
     status, String.valueOf(System.currentTimeMillis()), 
     true); 

     return (instance.getAppName() + " - " + instance.getId() + " result: " + isSuccess); 
    } 

    /** 
    * Application Name Predicate 
    * @param applicationNameCriteria 
    * @return 
    */ 
    private Predicate<Application> hasApplication(final String applicationNameCriteria) 
    { 
     return application -> applicationNameCriteria.toUpperCase().equals(application.getName()); 
    } 

    /** 
    * Instance Version Predicate. Uses Eureka Instance Metadata value name "version".</br> 
    * 
    * Set/Bake the instance metadata map to contain a version value.</br> 
    * e.g. eureka.instance.metadataMap.version=85839c2 
    * 
    * @param versionCriteria 
    * @return 
    */ 
    private Predicate<InstanceInfo> hasVersion(final String versionCriteria) 
    { 
     return info -> versionCriteria.equals(info.getMetadata().get("version")); 
    } 

    private PeerAwareInstanceRegistry getRegistry() { 
     return EurekaServerContextHolder.getInstance().getServerContext().getRegistry(); 
    } 
} 
+0

अच्छा विचार। मैं भी इसमें देख रहा हूँ। लेकिन मुझे यूरेका पक्ष पर ऐसा करने के बारे में निश्चित नहीं है - अगर सेवा एक नई दिल की धड़कन भेजती है, तो क्या यह फिर से अपने राज्य को यूपी में नहीं बदलेगी? स्प्रिंग क्लाउड के साथ आता है/रोकें और/एंड्यूपॉइंट फिर से शुरू करें, जो मुझे लगता है कि क्लाइंट स्थिति को OUT_OF_SERVICE या नीचे बदलता है। मैं एक तैनाती स्क्रिप्ट के बारे में सोच रहा था जो तैनाती से पहले जमा/रोकता है। इसे प्रस्तुत करने के उदाहरणों की सूची अभी भी यूरेका से खींचा जा सकता है और संस्करण या कुछ द्वारा फ़िल्टर किया जा सकता है। – nedenom

+0

मैं भी OUT_OF_SERVICE स्थिति में देख रहा था। से क्या मैं समझता हूँ, ऐसा लगता है एस्गर्ड एक समान दृष्टिकोण लेता है की तरह: https://github.com/Netflix/asgard/wiki/Eureka-Integration मेरा निष्कर्ष है कि, क्रम में PWS पर रोलिंग अद्यतन लागू करने के लिए है, हम एक की जरूरत है कस्टम, होमब्रेन्ड डैशबोर्ड (जैसे Asgard) जो इसे सुविधाजनक बनाएगा। पीडब्ल्यूएस दृश्य ऐसा करने के लिए बहुत सीमित है। AFAIK कोई वसंत पुस्तकालय नहीं है जो यह करता है। मुझे एहसास हुआ कि नहीं था मैं इसके लिए अपने खुद के बाकी अंतिमबिंदुओं को विकसित कर सकता के रूप में तुमने किया था, इसलिए मैं बाहर यूरेका के ही REST API के साथ शुरू कर दिया। मैं उस पर एक नज़र डालेंगे - धन्यवाद! –

+0

@nedenom अगर आप नीचे स्थिति सेट करते हैं तो यह 30 सेकंड के बाद स्वचालित रूप से यूपी पर सेट हो जाएगा। यदि आप स्थिति को OUT_OF_SERVICE पर सेट करते हैं, तो यह तब तक रहेगा जब तक आप मैन्युअल रूप से (आरईएसटी एपीआई के माध्यम से) इसे वापस यूपी/डाउन सेट न करें। –

संबंधित मुद्दे

 संबंधित मुद्दे